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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/out/replicache/src/dag/gc.d.ts.map +1 -1
  2. package/out/replicache/src/dag/gc.js +2 -1
  3. package/out/replicache/src/dag/gc.js.map +1 -1
  4. package/out/replicache/src/dag/invalid-ref-count-error.d.ts +12 -0
  5. package/out/replicache/src/dag/invalid-ref-count-error.d.ts.map +1 -0
  6. package/out/replicache/src/dag/invalid-ref-count-error.js +19 -0
  7. package/out/replicache/src/dag/invalid-ref-count-error.js.map +1 -0
  8. package/out/replicache/src/dag/store-impl.d.ts +12 -2
  9. package/out/replicache/src/dag/store-impl.d.ts.map +1 -1
  10. package/out/replicache/src/dag/store-impl.js +22 -8
  11. package/out/replicache/src/dag/store-impl.js.map +1 -1
  12. package/out/replicache/src/db/rebase.d.ts +14 -2
  13. package/out/replicache/src/db/rebase.d.ts.map +1 -1
  14. package/out/replicache/src/db/rebase.js +27 -5
  15. package/out/replicache/src/db/rebase.js.map +1 -1
  16. package/out/replicache/src/persist/collect-idb-databases.d.ts +10 -5
  17. package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
  18. package/out/replicache/src/persist/collect-idb-databases.js +16 -9
  19. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  20. package/out/replicache/src/persist/persist.d.ts.map +1 -1
  21. package/out/replicache/src/persist/persist.js +12 -5
  22. package/out/replicache/src/persist/persist.js.map +1 -1
  23. package/out/replicache/src/persist/refresh.js +6 -2
  24. package/out/replicache/src/persist/refresh.js.map +1 -1
  25. package/out/replicache/src/replicache-impl.d.ts +7 -3
  26. package/out/replicache/src/replicache-impl.d.ts.map +1 -1
  27. package/out/replicache/src/replicache-impl.js +98 -11
  28. package/out/replicache/src/replicache-impl.js.map +1 -1
  29. package/out/replicache/src/replicache-options.d.ts +9 -0
  30. package/out/replicache/src/replicache-options.d.ts.map +1 -1
  31. package/out/shared/src/iterables.d.ts +2 -0
  32. package/out/shared/src/iterables.d.ts.map +1 -1
  33. package/out/shared/src/iterables.js +18 -1
  34. package/out/shared/src/iterables.js.map +1 -1
  35. package/out/shared/src/ring-buffer.d.ts +8 -0
  36. package/out/shared/src/ring-buffer.d.ts.map +1 -1
  37. package/out/shared/src/ring-buffer.js +22 -1
  38. package/out/shared/src/ring-buffer.js.map +1 -1
  39. package/out/zero/package.js +2 -3
  40. package/out/zero/package.js.map +1 -1
  41. package/out/zero-cache/src/config/zero-config.js +2 -2
  42. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  43. package/out/zero-cache/src/server/change-streamer.js +1 -1
  44. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  45. package/out/zero-cache/src/server/inspector-delegate.d.ts +18 -2
  46. package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
  47. package/out/zero-cache/src/server/inspector-delegate.js +20 -7
  48. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  49. package/out/zero-cache/src/services/change-source/pg/backfill-resume.d.ts +156 -0
  50. package/out/zero-cache/src/services/change-source/pg/backfill-resume.d.ts.map +1 -0
  51. package/out/zero-cache/src/services/change-source/pg/backfill-resume.js +15 -0
  52. package/out/zero-cache/src/services/change-source/pg/backfill-resume.js.map +1 -0
  53. package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts +15 -0
  54. package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts.map +1 -0
  55. package/out/zero-cache/src/services/change-source/pg/change-source-init.js +99 -0
  56. package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -0
  57. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +14 -16
  58. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  59. package/out/zero-cache/src/services/change-source/pg/change-source.js +33 -126
  60. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  61. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +16 -1
  62. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  63. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +8 -4
  64. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  65. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts +16 -0
  66. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts.map +1 -0
  67. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +113 -0
  68. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -0
  69. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +1 -15
  70. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
  71. package/out/zero-cache/src/services/change-source/pg/replication-slots.js +18 -21
  72. package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
  73. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +8 -9
  74. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  75. package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts +17 -1
  76. package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts.map +1 -1
  77. package/out/zero-cache/src/services/change-streamer/upstream-acker.js +19 -3
  78. package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
  79. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts.map +1 -1
  80. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js +1 -0
  81. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js.map +1 -1
  82. package/out/zero-cache/src/services/replicator/change-processor.js +1 -0
  83. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  84. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts +14 -1
  85. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -1
  86. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +30 -4
  87. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  88. package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +1 -1
  89. package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts.map +1 -1
  90. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +2 -2
  91. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  92. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  93. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +6 -10
  94. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  95. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  96. package/out/zero-cache/src/services/view-syncer/view-syncer.js +14 -4
  97. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  98. package/out/zero-cache/src/types/streams.d.ts.map +1 -1
  99. package/out/zero-cache/src/types/streams.js +1 -1
  100. package/out/zero-cache/src/types/streams.js.map +1 -1
  101. package/out/zero-client/src/client/connection-manager.d.ts +20 -0
  102. package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
  103. package/out/zero-client/src/client/connection-manager.js +32 -14
  104. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  105. package/out/zero-client/src/client/connection-status-enum.d.ts +2 -0
  106. package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
  107. package/out/zero-client/src/client/connection-status-enum.js +3 -1
  108. package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
  109. package/out/zero-client/src/client/connection.d.ts +6 -0
  110. package/out/zero-client/src/client/connection.d.ts.map +1 -1
  111. package/out/zero-client/src/client/connection.js +2 -1
  112. package/out/zero-client/src/client/connection.js.map +1 -1
  113. package/out/zero-client/src/client/context.d.ts +8 -11
  114. package/out/zero-client/src/client/context.d.ts.map +1 -1
  115. package/out/zero-client/src/client/context.js +11 -15
  116. package/out/zero-client/src/client/context.js.map +1 -1
  117. package/out/zero-client/src/client/custom.js +2 -2
  118. package/out/zero-client/src/client/custom.js.map +1 -1
  119. package/out/zero-client/src/client/error.js +1 -1
  120. package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
  121. package/out/zero-client/src/client/mutator-proxy.js +2 -1
  122. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  123. package/out/zero-client/src/client/options.d.ts +3 -0
  124. package/out/zero-client/src/client/options.d.ts.map +1 -1
  125. package/out/zero-client/src/client/options.js.map +1 -1
  126. package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
  127. package/out/zero-client/src/client/query-manager.js +42 -6
  128. package/out/zero-client/src/client/query-manager.js.map +1 -1
  129. package/out/zero-client/src/client/version.js +1 -1
  130. package/out/zero-client/src/client/zero-rep.d.ts +1 -0
  131. package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
  132. package/out/zero-client/src/client/zero-rep.js +7 -5
  133. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  134. package/out/zero-client/src/client/zero.d.ts +9 -3
  135. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  136. package/out/zero-client/src/client/zero.js +48 -11
  137. package/out/zero-client/src/client/zero.js.map +1 -1
  138. package/out/zero-client/src/types/query-result.d.ts +2 -0
  139. package/out/zero-client/src/types/query-result.d.ts.map +1 -1
  140. package/out/zero-react/src/use-query.d.ts +5 -4
  141. package/out/zero-react/src/use-query.d.ts.map +1 -1
  142. package/out/zero-react/src/use-query.js +12 -1
  143. package/out/zero-react/src/use-query.js.map +1 -1
  144. package/out/zero-server/src/adapters/drizzle.d.ts +2 -1
  145. package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -1
  146. package/out/zero-server/src/adapters/drizzle.js +12 -7
  147. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  148. package/out/zero-server/src/adapters/kysely.d.ts +2 -1
  149. package/out/zero-server/src/adapters/kysely.d.ts.map +1 -1
  150. package/out/zero-server/src/adapters/kysely.js +8 -2
  151. package/out/zero-server/src/adapters/kysely.js.map +1 -1
  152. package/out/zero-server/src/adapters/pg.d.ts +1 -0
  153. package/out/zero-server/src/adapters/pg.d.ts.map +1 -1
  154. package/out/zero-server/src/adapters/pg.js +8 -2
  155. package/out/zero-server/src/adapters/pg.js.map +1 -1
  156. package/out/zero-server/src/adapters/postgresjs.d.ts +1 -0
  157. package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
  158. package/out/zero-server/src/adapters/postgresjs.js +7 -1
  159. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  160. package/out/zero-server/src/adapters/prisma.d.ts +3 -2
  161. package/out/zero-server/src/adapters/prisma.d.ts.map +1 -1
  162. package/out/zero-server/src/adapters/prisma.js +8 -2
  163. package/out/zero-server/src/adapters/prisma.js.map +1 -1
  164. package/out/zero-server/src/custom.d.ts +5 -1
  165. package/out/zero-server/src/custom.d.ts.map +1 -1
  166. package/out/zero-server/src/custom.js +6 -3
  167. package/out/zero-server/src/custom.js.map +1 -1
  168. package/out/zero-server/src/mod.d.ts +1 -1
  169. package/out/zero-server/src/mod.d.ts.map +1 -1
  170. package/out/zero-server/src/pg-query-executor.d.ts +2 -2
  171. package/out/zero-server/src/pg-query-executor.d.ts.map +1 -1
  172. package/out/zero-server/src/pg-query-executor.js +2 -2
  173. package/out/zero-server/src/pg-query-executor.js.map +1 -1
  174. package/out/zero-server/src/schema.d.ts +2 -2
  175. package/out/zero-server/src/schema.d.ts.map +1 -1
  176. package/out/zero-server/src/schema.js +2 -2
  177. package/out/zero-server/src/schema.js.map +1 -1
  178. package/out/zero-server/src/zql-database.d.ts +21 -1
  179. package/out/zero-server/src/zql-database.d.ts.map +1 -1
  180. package/out/zero-server/src/zql-database.js +33 -2
  181. package/out/zero-server/src/zql-database.js.map +1 -1
  182. package/out/zero-solid/src/solid-view.d.ts +10 -0
  183. package/out/zero-solid/src/solid-view.d.ts.map +1 -1
  184. package/out/zero-solid/src/solid-view.js +27 -0
  185. package/out/zero-solid/src/solid-view.js.map +1 -1
  186. package/out/zql/src/ivm/array-view.d.ts +10 -0
  187. package/out/zql/src/ivm/array-view.d.ts.map +1 -1
  188. package/out/zql/src/ivm/array-view.js +20 -8
  189. package/out/zql/src/ivm/array-view.js.map +1 -1
  190. package/out/zql/src/ivm/cap.d.ts.map +1 -1
  191. package/out/zql/src/ivm/cap.js +5 -3
  192. package/out/zql/src/ivm/cap.js.map +1 -1
  193. package/out/zql/src/ivm/deferred-input.d.ts.map +1 -1
  194. package/out/zql/src/ivm/deferred-input.js +3 -2
  195. package/out/zql/src/ivm/deferred-input.js.map +1 -1
  196. package/out/zql/src/ivm/exists.d.ts +1 -1
  197. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  198. package/out/zql/src/ivm/exists.js.map +1 -1
  199. package/out/zql/src/ivm/fan-in.d.ts +2 -2
  200. package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
  201. package/out/zql/src/ivm/fan-in.js +6 -5
  202. package/out/zql/src/ivm/fan-in.js.map +1 -1
  203. package/out/zql/src/ivm/fan-out.d.ts +2 -2
  204. package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
  205. package/out/zql/src/ivm/fan-out.js.map +1 -1
  206. package/out/zql/src/ivm/filter-operators.d.ts +6 -6
  207. package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
  208. package/out/zql/src/ivm/filter-operators.js +10 -8
  209. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  210. package/out/zql/src/ivm/filter.d.ts +2 -2
  211. package/out/zql/src/ivm/filter.d.ts.map +1 -1
  212. package/out/zql/src/ivm/filter.js +7 -4
  213. package/out/zql/src/ivm/filter.js.map +1 -1
  214. package/out/zql/src/ivm/flipped-join.js +2 -2
  215. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  216. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
  217. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
  218. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +6 -4
  219. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  220. package/out/zql/src/ivm/memory-source.d.ts +2 -2
  221. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  222. package/out/zql/src/ivm/memory-source.js +9 -9
  223. package/out/zql/src/ivm/memory-source.js.map +1 -1
  224. package/out/zql/src/ivm/take.d.ts.map +1 -1
  225. package/out/zql/src/ivm/take.js +3 -4
  226. package/out/zql/src/ivm/take.js.map +1 -1
  227. package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
  228. package/out/zql/src/ivm/union-fan-in.js +9 -7
  229. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  230. package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
  231. package/out/zql/src/ivm/view-apply-change.js +3 -3
  232. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  233. package/out/zql/src/mutate/custom.d.ts +24 -1
  234. package/out/zql/src/mutate/custom.d.ts.map +1 -1
  235. package/out/zql/src/mutate/custom.js.map +1 -1
  236. package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
  237. package/out/zql/src/mutate/mutator-registry.js +2 -2
  238. package/out/zql/src/mutate/mutator-registry.js.map +1 -1
  239. package/out/zql/src/query/query-delegate-base.d.ts +2 -0
  240. package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
  241. package/out/zql/src/query/query-delegate-base.js +55 -28
  242. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  243. package/out/zql/src/query/query-delegate.d.ts +11 -1
  244. package/out/zql/src/query/query-delegate.d.ts.map +1 -1
  245. package/out/zql/src/query/query-impl.d.ts +1 -0
  246. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  247. package/out/zql/src/query/query-impl.js.map +1 -1
  248. package/out/zql/src/query/query.d.ts +7 -1
  249. package/out/zql/src/query/query.d.ts.map +1 -1
  250. package/out/zql/src/query/runnable-query-impl.d.ts +1 -0
  251. package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
  252. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  253. package/out/zql/src/query/typed-view.d.ts +1 -1
  254. package/out/zql/src/query/typed-view.d.ts.map +1 -1
  255. package/out/zqlite/src/table-source.d.ts.map +1 -1
  256. package/out/zqlite/src/table-source.js +7 -5
  257. package/out/zqlite/src/table-source.js.map +1 -1
  258. package/package.json +2 -3
@@ -1 +1 @@
1
- {"version":3,"file":"view-apply-change.js","names":[],"sources":["../../../../../zql/src/ivm/view-apply-change.ts"],"sourcesContent":["import {\n assert,\n assertNumber,\n unreachable,\n} from '../../../shared/src/asserts.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport {assignProperty} from '../../../shared/src/objects.ts';\nimport type {Writable} from '../../../shared/src/writable.ts';\nimport type {Row} from '../../../zero-protocol/src/data.ts';\nimport {type Comparator, type Node} from './data.ts';\nimport {skipYields} from './operator.ts';\nimport type {SourceSchema} from './schema.ts';\nimport type {Entry, Format} from './view.ts';\n\nexport const refCountSymbol = Symbol('rc');\nexport const idSymbol = Symbol('id');\n\ntype ReadonlyMetaEntry = Entry & {\n readonly [refCountSymbol]: number;\n readonly [idSymbol]?: string | undefined;\n};\n\ntype MutableMetaEntry = Writable<ReadonlyMetaEntry>;\n\n/**\n * MetaEntry is an Entry with internal tracking fields for reference counting\n * and stable identity. All entries in the view tree are MetaEntry instances,\n * created through makeNewMetaEntry().\n */\ntype MetaEntry<M extends Mutate> = M extends true\n ? MutableMetaEntry\n : ReadonlyMetaEntry;\n\ntype MutableArray<M extends Mutate, T> = M extends true ? T[] : readonly T[];\n\ntype MetaEntryList<M extends Mutate> = MutableArray<M, MetaEntry<M>>;\n\ntype MutableMetaEntryList = MutableMetaEntry[];\n\n/**\n * Node with eagerly-expanded relationships (arrays instead of generators).\n * Used when batching changes to capture source state at push time.\n */\nexport type ExpandedNode = {\n row: Row;\n relationships: Record<string, ExpandedNode[]>;\n};\n\n/**\n * A node for view changes. Can be either:\n * - A lazy Node with generator relationships (original behavior)\n * - An ExpandedNode with pre-computed relationship arrays (for batching)\n */\nexport type ViewNode = Node | ExpandedNode;\n\n/**\n * `applyChange` does not consume the `relationships` of `ChildChange#node`,\n * `EditChange#node` and `EditChange#oldNode`. The `ViewChange` type\n * documents and enforces this via the type system.\n */\nexport type ViewChange =\n | AddViewChange\n | RemoveViewChange\n | ChildViewChange\n | EditViewChange;\n\nexport type RowOnlyNode = {row: Row};\n\nexport type AddViewChange = {\n type: 'add';\n node: ViewNode;\n};\n\nexport type RemoveViewChange = {\n type: 'remove';\n node: ViewNode;\n};\n\ntype ChildViewChange = {\n type: 'child';\n node: RowOnlyNode;\n child: {\n relationshipName: string;\n change: ViewChange;\n };\n};\n\ntype EditViewChange = {\n type: 'edit';\n node: RowOnlyNode;\n oldNode: RowOnlyNode;\n};\n\n/**\n * This is a subset of WeakMap but restricted to what we need.\n * @deprecated Not used anymore. This will be removed in the future.\n */\nexport interface RefCountMap {\n get(entry: Entry): number | undefined;\n set(entry: Entry, refCount: number): void;\n delete(entry: Entry): boolean;\n}\n\n/**\n * Get child nodes from a relationship, handling both lazy (Node) and expanded (ExpandedNode).\n */\nfunction* getChildNodes(\n node: ViewNode,\n relationship: string,\n): Generator<ViewNode> {\n const children = node.relationships[relationship];\n if (Array.isArray(children)) {\n // ExpandedNode: already an array\n yield* children;\n } else {\n // Node: lazy generator function\n yield* skipYields(children());\n }\n}\n\ntype Mutate = boolean;\ntype WithIDs = boolean;\n\n/**\n * Transaction-scoped copy-on-write.\n *\n * `applyChange` is immutable: it path-copies a new spine on every call so the\n * previously-emitted snapshot is never mutated. But within a single transaction\n * (a run of `push()` calls before `flush()`) only the final state is ever\n * observed by a listener, so the intermediate spines are pure allocation/GC\n * churn — making a K-change transaction O(K * spineSize).\n *\n * When the caller passes a WeakSet as the `mutate` argument, objects and arrays\n * that were created or cloned during the current transaction are recorded in it.\n * A helper that needs to modify such an object mutates it in place (it is not\n * yet observed) instead of cloning again. The first touch of a node still\n * copies-on-write (preserving the committed snapshot's references); subsequent\n * touches in the same transaction are in-place. This brings a K-change\n * transaction to O(spineSize + K) while keeping cross-transaction reference\n * stability.\n *\n * The set is module-scoped for the duration of a single (synchronous,\n * non-re-entrant) `applyChange` call and saved/restored around it.\n *\n * It is a WeakSet on purpose: it must not keep transiently-cloned arrays/entries\n * alive. A strong Set would extend their lifetime to the end of the transaction,\n * pushing large clones out of the young generation and adding GC pressure that\n * shows up as a regression on single-change transactions over wide lists. A\n * WeakSet gives the same identity test (\"created this transaction?\") while\n * letting dead clones be collected as cheaply as in the plain immutable path.\n */\nlet activeDirty: WeakSet<object> | undefined;\n\n/** True if `o` was created/cloned during the current transaction. */\nfunction owns(o: object): boolean {\n return activeDirty !== undefined && activeDirty.has(o);\n}\n\n/** Record `o` as owned by the current transaction (no-op outside a txn). */\nfunction track<T extends object>(o: T): T {\n activeDirty?.add(o);\n return o;\n}\n\n/**\n * Immutable view update. Returns new Entry on change, same Entry if unchanged.\n * Unchanged entries keep identity, enabling shallow comparison optimizations\n * in UI frameworks (React.memo, Solid's fine-grained reactivity, etc).\n *\n * Propagation: recurse DOWN to find target, copy objects on the way UP.\n * Siblings keep original refs. Only the ancestor path is copied.\n *\n * root {users:[A,B], items:[C,D,E]} --edit C--> root' {users:[A,B], items':[C',D,E]}\n * │ same ref │ │ │\n * └─────────────────┴── unchanged ──────────────┘ new array C' new, D/E same\n *\n * `mutate` selects the update strategy:\n * - `false` (default): fully immutable; every changed node is path-copied.\n * - `true`: mutate the tree in place (only safe when it is not yet observed,\n * e.g. during initial hydration).\n * - a `WeakSet`: transaction-scoped copy-on-write — copy on first touch, then\n * mutate in place for the rest of the transaction. See `activeDirty` above.\n */\nexport function applyChange(\n parentEntry: Entry,\n change: ViewChange,\n schema: SourceSchema,\n relationship: string,\n format: Format,\n withIDs = false,\n mutate: boolean | WeakSet<object> = false,\n): Entry {\n // A WeakSet selects copy-on-write; a boolean selects full mutate / immutable.\n const inPlace = mutate === true;\n const prevDirty = activeDirty;\n activeDirty = typeof mutate === 'object' ? mutate : undefined;\n try {\n return applyChangeInternal(\n parentEntry as MetaEntry<typeof inPlace>,\n change,\n schema,\n relationship,\n format,\n withIDs,\n inPlace,\n );\n } finally {\n activeDirty = prevDirty;\n }\n}\n\nexport function applyChangeInternal<M extends Mutate>(\n parentEntry: MetaEntry<M>,\n change: ViewChange,\n schema: SourceSchema,\n relationship: string,\n format: Format,\n withIDs: WithIDs,\n mutate: M,\n): MetaEntry<M> {\n if (schema.isHidden) {\n switch (change.type) {\n case 'add':\n case 'remove': {\n let currentParent = parentEntry;\n for (const relationship of Object.keys(change.node.relationships)) {\n const childSchema = must(schema.relationships[relationship]);\n for (const node of getChildNodes(change.node, relationship)) {\n currentParent = applyChangeInternal(\n currentParent,\n {type: change.type, node},\n childSchema,\n relationship,\n format,\n withIDs,\n mutate,\n );\n }\n }\n return currentParent;\n }\n case 'edit':\n // If hidden at this level it means that the hidden row was changed. If\n // the row was changed in such a way that it would change the\n // relationships then the edit would have been split into remove and\n // add.\n return parentEntry;\n case 'child': {\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n return applyChangeInternal(\n parentEntry,\n change.child.change,\n childSchema,\n relationship,\n format,\n withIDs,\n mutate,\n );\n }\n default:\n unreachable(change);\n }\n }\n\n const {singular, relationships: childFormats} = format;\n switch (change.type) {\n // ADD: Insert row (rc=1) or increment refCount if duplicate.\n // RefCount tracks when the same row is reachable via multiple edges\n // within a relationship:\n //\n // issue.labels: [L1, L2] both point to same creator\n // │ │ │\n // ▼ ▼ ▼\n // label.creator ──────────► [User:rc=2] (one row, two refs)\n //\n // add(A) add(A) remove(A) remove(A)\n // ↓ ↓ ↓ ↓\n // [A:rc=1] → [A:rc=2] → [A:rc=1] → (deleted)\n case 'add': {\n if (singular) {\n const oldEntry = getOptionalSingularEntry(parentEntry, relationship);\n if (oldEntry !== undefined) {\n // Duplicate add: increment refCount\n assert(\n schema.compareRows(oldEntry, change.node.row) === 0,\n `Singular relationship '${relationship}' should not have multiple rows. You may need to declare this relationship with the \\`many\\` helper instead of the \\`one\\` helper in your schema.`,\n );\n\n const newEntry = incRefCount(mutate, oldEntry);\n return setRelation(mutate, parentEntry, relationship, newEntry);\n } else {\n // New row: create with rc=1, initialize nested relationships\n const newEntry = makeNewMetaEntry(\n change.node.row,\n schema,\n withIDs,\n 1,\n );\n initializeRelationshipsForNewEntryIfAny(\n newEntry,\n change.node,\n schema,\n childFormats,\n withIDs,\n );\n return setRelation(mutate, parentEntry, relationship, newEntry);\n }\n } else {\n // Plural: binary search for position, insert or increment refCount\n const view = getChildEntryList(parentEntry, relationship);\n const {newEntry, newView} = add(\n change.node.row,\n view,\n schema,\n withIDs,\n mutate,\n );\n\n if (newEntry) {\n initializeRelationshipsForNewEntryIfAny(\n newEntry,\n change.node,\n schema,\n childFormats,\n withIDs,\n );\n }\n return setRelation(mutate, parentEntry, relationship, newView);\n }\n }\n // REMOVE: Decrement refCount, physically remove when rc=0.\n case 'remove': {\n if (singular) {\n const oldEntry = getSingularEntry(parentEntry, relationship);\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n return setRelation(mutate, parentEntry, relationship, undefined);\n }\n const newEntry = decRefCount(mutate, oldEntry);\n return setRelation(mutate, parentEntry, relationship, newEntry);\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n const newView = removeAndUpdateRefCount(\n view,\n change.node.row,\n schema.compareRows,\n mutate,\n );\n return setRelation(mutate, parentEntry, relationship, newView);\n }\n }\n // CHILD: Propagate nested change up to this level (leaf-to-root pattern).\n case 'child': {\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n const childFormat = format.relationships[change.child.relationshipName];\n if (childFormat === undefined) {\n return parentEntry; // Relationship not in view format\n }\n\n if (singular) {\n const existing = getSingularEntry(parentEntry, relationship);\n const newExisting = applyChangeInternal(\n existing,\n change.child.change,\n childSchema,\n change.child.relationshipName,\n childFormat,\n withIDs,\n mutate,\n );\n // Preserve identity if child didn't change (enables shallow-compare optimizations).\n if (newExisting === existing) {\n return parentEntry;\n }\n return setRelation(mutate, parentEntry, relationship, newExisting);\n } else {\n // Find the target row in the sorted array via binary search.\n const view = getChildEntryList(parentEntry, relationship);\n const pos = binarySearch(view, change.node.row, schema.compareRows);\n assert(pos >= 0, 'node does not exist');\n const existing = view[pos];\n const newExisting = applyChangeInternal(\n existing,\n change.child.change,\n childSchema,\n change.child.relationshipName,\n childFormat,\n withIDs,\n mutate,\n );\n // Preserve identity if descendant didn't change.\n if (newExisting === existing) {\n return parentEntry;\n }\n // applyChangeInternal preserves MetaEntry structure when input is MetaEntry\n assertMetaEntry(newExisting);\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n arrayWith(mutate, view, pos, newExisting),\n );\n }\n }\n // EDIT: Update row fields. If sort key changes, row may move position.\n //\n // Position change with rc>1 (two query paths reach same row):\n //\n // Before: [A, B(rc=2), C, D] After: [A, B(rc=1), C, B'(rc=1), D]\n // │ │ │\n // path1 + path2 path1 ghost path2 moved\n //\n // Why ghost stays: path1 still expects B at old position.\n // B' appears where path2's sort order places it.\n case 'edit': {\n if (singular) {\n const existing = getSingularEntry(parentEntry, relationship);\n const newEntry = applyEdit(existing, change, schema, withIDs, mutate);\n return setRelation(mutate, parentEntry, relationship, newEntry);\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n // Sort key changed: row may need to move\n if (schema.compareRows(change.oldNode.row, change.node.row) !== 0) {\n const oldPos = binarySearch(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n assert(oldPos >= 0, 'old node does not exist');\n const oldEntry = view[oldPos];\n const rawPos = binarySearch(\n view,\n change.node.row,\n schema.compareRows,\n );\n const found = rawPos >= 0;\n const pos = found ? rawPos : ~rawPos;\n // A special case:\n // when refCount is 1 (so the row is being moved without leaving a\n // placeholder behind), and the new pos is the same as the old, or\n // directly after the old (so after the remove of the old it would be\n // in the same pos): the row does not need to be moved, just edited.\n if (\n oldEntry[refCountSymbol] === 1 &&\n (pos === oldPos || pos - 1 === oldPos)\n ) {\n const newEntry = applyEdit(\n oldEntry,\n change,\n schema,\n withIDs,\n mutate,\n );\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n arrayWith(mutate, view, oldPos, newEntry),\n );\n } else {\n // Move the row. If rc > 1, an edit will be received for each ref.\n // On first edit: move row, apply edit, set rc=1. Leave a copy at\n // old pos with decremented rc. As each edit arrives, old copy's rc\n // decrements and new pos rc increments. When copy rc hits 0, remove.\n const newRefCount = oldEntry[refCountSymbol] - 1;\n let newView: MutableMetaEntryList;\n let adjustedPos = pos;\n\n if (newRefCount === 0) {\n newView = removeAt(mutate, view, oldPos);\n adjustedPos = oldPos < pos ? pos - 1 : pos;\n } else {\n const oldEntryCopy = setRefCount(mutate, oldEntry, newRefCount);\n newView = arrayWith(mutate, view, oldPos, oldEntryCopy);\n }\n\n if (found) {\n // Merge with existing at new pos\n const existingEntry = newView[adjustedPos];\n const editedEntry = applyEdit(\n existingEntry,\n change,\n schema,\n withIDs,\n mutate,\n );\n const updatedEntry = setRefCount(\n mutate,\n editedEntry,\n existingEntry[refCountSymbol] + 1,\n );\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n arrayWith(mutate, newView, adjustedPos, updatedEntry),\n );\n } else {\n // Insert at new pos with rc=1\n const editedEntry = applyEdit(\n oldEntry,\n change,\n schema,\n withIDs,\n mutate,\n );\n const movedEntry = setRefCount(mutate, editedEntry, 1);\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n insertAt(mutate, newView, adjustedPos, movedEntry),\n );\n }\n }\n } else {\n // Sort key unchanged: edit in place\n const pos = binarySearch(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n assert(pos >= 0, 'node does not exist');\n const newEntry = applyEdit(\n view[pos],\n change,\n schema,\n withIDs,\n mutate,\n );\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n arrayWith(mutate, view, pos, newEntry),\n );\n }\n }\n }\n default:\n unreachable(change);\n }\n}\n\n/**\n * Batch apply multiple changes to an Entry tree.\n * For small batches or complex cases, falls back to sequential applyChange.\n * Future optimization: O(N + K) batch processing for large K.\n */\nexport function applyChanges(\n parentEntry: Entry,\n changes: ViewChange[],\n schema: SourceSchema,\n relationship: string,\n format: Format,\n withIDs: WithIDs = false,\n mutate: Mutate = false,\n): Entry {\n let result = parentEntry;\n for (const change of changes) {\n result = applyChange(\n result,\n change,\n schema,\n relationship,\n format,\n withIDs,\n mutate,\n );\n }\n return result;\n}\n\nfunction applyEdit<M extends Mutate>(\n existing: MetaEntry<M>,\n change: EditViewChange,\n schema: SourceSchema,\n withIDs: WithIDs,\n mutate: Mutate,\n): MetaEntry<M> {\n // In-place edit is safe when fully mutating or when `existing` was already\n // created/cloned in this transaction (copy-on-write). A primary-key change\n // always needs a fresh entry so identity tracks the new key.\n const canMutate = mutate || owns(existing);\n const newEntry: MutableMetaEntry =\n canMutate && schema.compareRows(change.oldNode.row, change.node.row) === 0\n ? Object.assign(existing, change.node.row)\n : track({...existing, ...change.node.row});\n\n if (withIDs) {\n return setProperty(\n mutate,\n newEntry,\n idSymbol,\n makeID(change.node.row, schema),\n );\n }\n return newEntry;\n}\n\n/**\n * Initialize child relationships on a newly-added entry by mutating it in place.\n *\n * New nodes don't exist in the view yet, so we can build in-place (no refs to preserve):\n *\n * New nodes don't exist in the view yet, so we can build in-place (no refs to preserve):\n *\n * Existing node edit (must path-copy): New node (can build in-place):\n *\n * view: [A, B, C] view: [A, B, _]\n * │ │\n * edit C.child add C with children\n * │ │\n * ▼ ▼\n * view': [A, B, C'] ◄─ path-copy view': [A, B, C{children:[...]}]\n * up the tree └─ built in-place\n *\n * Hidden schemas still use applyChange to collapse junction levels.\n */\nfunction initializeRelationshipsForNewEntryIfAny(\n entry: MutableMetaEntry,\n node: ViewNode,\n schema: SourceSchema,\n childFormats: Record<string, Format>,\n withIDs: WithIDs,\n): void {\n let result = entry;\n for (const relationship of Object.keys(node.relationships)) {\n const childSchema = must(schema.relationships[relationship]);\n const childFormat = childFormats[relationship];\n if (childFormat === undefined) {\n continue;\n }\n\n // Hidden/singular: use applyChange to handle properly\n if (childSchema.isHidden || childFormat.singular) {\n const newView = childFormat.singular\n ? undefined\n : track([] as MutableMetaEntryList);\n result[relationship] = newView;\n\n for (const childNode of getChildNodes(node, relationship)) {\n applyChangeInternal(\n result,\n {type: 'add', node: childNode},\n childSchema,\n relationship,\n childFormat,\n withIDs,\n true, // this is a new entry, so we can mutate\n );\n }\n } else {\n // Plural non-hidden: build array in-place for efficiency\n const childArray: MutableMetaEntryList = track([]);\n\n for (const childNode of getChildNodes(node, relationship)) {\n const newEntry = makeNewMetaEntry(\n childNode.row,\n childSchema,\n withIDs,\n 1,\n );\n const rawPos = binarySearch(\n childArray,\n childNode.row,\n childSchema.compareRows,\n );\n\n if (rawPos >= 0) {\n childArray[rawPos][refCountSymbol]++;\n } else {\n childArray.splice(~rawPos, 0, newEntry);\n initializeRelationshipsForNewEntryIfAny(\n newEntry,\n childNode,\n childSchema,\n childFormat.relationships,\n withIDs,\n );\n }\n }\n\n result[relationship] = childArray;\n }\n }\n}\n\nfunction add<M extends Mutate>(\n row: Row,\n view: MetaEntryList<M>,\n schema: SourceSchema,\n withIDs: WithIDs,\n mutate: M,\n): {\n newEntry: MutableMetaEntry | undefined;\n newView: MutableMetaEntryList;\n} {\n const rawPos = binarySearch(view, row, schema.compareRows);\n\n if (rawPos >= 0) {\n const existing = view[rawPos];\n\n const updated = incRefCount(mutate, existing);\n return {\n newEntry: undefined,\n newView: arrayWith(mutate, view, rawPos, updated),\n };\n }\n const newEntry = makeNewMetaEntry(row, schema, withIDs, 1);\n return {newEntry, newView: insertAt(mutate, view, ~rawPos, newEntry)};\n}\n\nfunction insertAt<M extends Mutate, T>(\n mutate: M,\n array: MutableArray<M, T>,\n index: number,\n item: T,\n): T[] {\n if (mutate || owns(array)) {\n (array as T[]).splice(index, 0, item);\n return array as T[];\n }\n return track(array.toSpliced(index, 0, item));\n}\n\nfunction removeAt<M extends Mutate, T>(\n mutate: M,\n array: MutableArray<M, T>,\n index: number,\n): T[] {\n if (mutate || owns(array)) {\n (array as T[]).splice(index, 1);\n return array as T[];\n }\n return track(array.toSpliced(index, 1));\n}\n\nfunction removeAndUpdateRefCount<M extends Mutate>(\n view: MetaEntryList<M>,\n row: Row,\n compareRows: Comparator,\n mutate: M,\n): MutableMetaEntryList {\n const pos = binarySearch(view, row, compareRows);\n assert(pos >= 0, 'node does not exist');\n const oldEntry = view[pos];\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n return removeAt(mutate, view, pos);\n }\n const newEntry = decRefCount(mutate, oldEntry);\n return arrayWith(mutate, view, pos, newEntry);\n}\n\n/**\n * Binary search returning a number.\n * - If found at index `i`: returns `i` (>= 0).\n * - If not found, insertion point is `low`: returns `~low` (< 0).\n * Recover insertion point with `~result`.\n */\nfunction binarySearch(\n view: MetaEntryList<Mutate>,\n target: Row,\n comparator: Comparator,\n): number {\n let high = view.length - 1;\n if (high < 0) {\n return ~0;\n }\n\n // Probe the last entry before searching. Hydration feeds the view rows in\n // the query's sort order, so every insert belongs at the end and the plain\n // search spends log2(n) comparisons to rediscover that -- about eleven per\n // row for a view of a couple of thousand. Row comparison is the single\n // largest cost in hydration on Hermes, so collapsing those eleven to one is\n // worth the one extra comparison this costs when the row does land inside\n // the view, which is a single push rather than a bulk load.\n // MetaEntry has all Row props; comparator only reads string keys\n const last = comparator(view[high] as Row, target);\n if (last < 0) {\n return ~(high + 1);\n }\n if (last === 0) {\n return high;\n }\n\n let low = 0;\n high -= 1;\n while (low <= high) {\n const mid = (low + high) >>> 1;\n const comparison = comparator(view[mid] as Row, target);\n if (comparison < 0) {\n low = mid + 1;\n } else if (comparison > 0) {\n high = mid - 1;\n } else {\n return mid;\n }\n }\n return ~low;\n}\n\n/** Assert value is MetaEntry (has refCountSymbol). */\nfunction assertMetaEntry<M extends Mutate>(\n v: unknown,\n): asserts v is MetaEntry<M> {\n assertNumber((v as Partial<MetaEntry<M>>)[refCountSymbol]);\n}\n\n/** Get singular MetaEntry, throws if missing. */\nfunction getSingularEntry<M extends Mutate>(\n parentEntry: MetaEntry<M>,\n relationship: string,\n): MetaEntry<M> {\n const entry = parentEntry[relationship];\n assert(entry !== undefined, 'node does not exist');\n assertMetaEntry(entry);\n return entry;\n}\n\n/** Get singular MetaEntry or undefined if not set. */\nfunction getOptionalSingularEntry<M extends Mutate>(\n parentEntry: MetaEntry<M>,\n relationship: string,\n): MetaEntry<M> | undefined {\n const entry = parentEntry[relationship];\n if (entry === undefined) {\n return undefined;\n }\n assertMetaEntry(entry);\n return entry;\n}\n\n/** Get child array as MetaEntryList. */\nfunction getChildEntryList<M extends Mutate>(\n parentEntry: MetaEntry<M>,\n relationship: string,\n): MetaEntryList<M> {\n const view = parentEntry[relationship];\n // `relationship` is a string key, so a name colliding with a column would\n // put a row value here; the message must not repeat it back.\n assert(Array.isArray(view), 'expected relationship array');\n return view as MetaEntryList<M>;\n}\n\n/** Create MetaEntry from row with given refCount. */\nfunction makeNewMetaEntry(\n row: Row,\n schema: SourceSchema,\n withIDs: WithIDs,\n rc: number,\n): MutableMetaEntry {\n // This creates a new MetaEntry from a Row. We never mutate Rows.\n if (withIDs) {\n return track({\n ...row,\n [refCountSymbol]: rc,\n [idSymbol]: makeID(row, schema),\n });\n }\n return track({\n ...row,\n [refCountSymbol]: rc,\n });\n}\n\nfunction makeID(row: Row, schema: SourceSchema) {\n // optimization for case of non-compound primary key\n if (schema.primaryKey.length === 1) {\n return JSON.stringify(row[schema.primaryKey[0]]);\n }\n return JSON.stringify(schema.primaryKey.map(k => row[k]));\n}\n\nfunction incRefCount<M extends Mutate>(\n mutate: M,\n entry: MetaEntry<M>,\n): MutableMetaEntry {\n return setRefCount(mutate, entry, entry[refCountSymbol] + 1);\n}\n\nfunction decRefCount<M extends Mutate>(\n mutate: M,\n entry: MetaEntry<M>,\n): MutableMetaEntry {\n return setRefCount(mutate, entry, entry[refCountSymbol] - 1);\n}\n\nfunction setRefCount<M extends Mutate>(\n mutate: M,\n entry: MetaEntry<M>,\n count: number,\n): MutableMetaEntry {\n if (mutate || owns(entry)) {\n (entry as MutableMetaEntry)[refCountSymbol] = count;\n return entry;\n }\n return track({\n ...entry,\n [refCountSymbol]: count,\n });\n}\n\nfunction arrayWith<M extends Mutate, T>(\n mutate: M,\n array: MutableArray<M, T>,\n index: number,\n value: T,\n): T[] {\n if (mutate || owns(array)) {\n (array as T[])[index] = value;\n return array as T[];\n }\n return track(array.with(index, value));\n}\n\nfunction setProperty<\n M extends Mutate,\n K extends string | keyof MetaEntry<M>,\n V,\n>(\n mutate: M,\n parentEntry: MetaEntry<M>,\n key: K,\n value: V,\n): MutableMetaEntry & {[P in K]: V} {\n if (mutate || owns(parentEntry)) {\n assignProperty(parentEntry as {[P in K]: V}, key, value);\n return parentEntry as MutableMetaEntry & {[P in K]: V};\n }\n return track({\n ...parentEntry,\n [key]: value,\n }) as MutableMetaEntry & {[P in K]: V};\n}\n\nconst setRelation: <M extends Mutate>(\n mutate: M,\n parentEntry: MetaEntry<M>,\n relationship: string,\n value: Entry | Entry[] | undefined,\n) => MutableMetaEntry = setProperty;\n"],"mappings":"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"}
1
+ {"version":3,"file":"view-apply-change.js","names":[],"sources":["../../../../../zql/src/ivm/view-apply-change.ts"],"sourcesContent":["import {\n assert,\n assertNumber,\n unreachable,\n} from '../../../shared/src/asserts.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport {assignProperty} from '../../../shared/src/objects.ts';\nimport type {Writable} from '../../../shared/src/writable.ts';\nimport type {Row} from '../../../zero-protocol/src/data.ts';\nimport {type Comparator, type Node} from './data.ts';\nimport {skipYields} from './operator.ts';\nimport type {SourceSchema} from './schema.ts';\nimport type {Entry, Format} from './view.ts';\n\nexport const refCountSymbol = Symbol('rc');\nexport const idSymbol = Symbol('id');\n\ntype ReadonlyMetaEntry = Entry & {\n readonly [refCountSymbol]: number;\n readonly [idSymbol]?: string | undefined;\n};\n\ntype MutableMetaEntry = Writable<ReadonlyMetaEntry>;\n\n/**\n * MetaEntry is an Entry with internal tracking fields for reference counting\n * and stable identity. All entries in the view tree are MetaEntry instances,\n * created through makeNewMetaEntry().\n */\ntype MetaEntry<M extends Mutate> = M extends true\n ? MutableMetaEntry\n : ReadonlyMetaEntry;\n\ntype MutableArray<M extends Mutate, T> = M extends true ? T[] : readonly T[];\n\ntype MetaEntryList<M extends Mutate> = MutableArray<M, MetaEntry<M>>;\n\ntype MutableMetaEntryList = MutableMetaEntry[];\n\n/**\n * Node with eagerly-expanded relationships (arrays instead of generators).\n * Used when batching changes to capture source state at push time.\n */\nexport type ExpandedNode = {\n row: Row;\n relationships: Record<string, ExpandedNode[]>;\n};\n\n/**\n * A node for view changes. Can be either:\n * - A lazy Node with generator relationships (original behavior)\n * - An ExpandedNode with pre-computed relationship arrays (for batching)\n */\nexport type ViewNode = Node | ExpandedNode;\n\n/**\n * `applyChange` does not consume the `relationships` of `ChildChange#node`,\n * `EditChange#node` and `EditChange#oldNode`. The `ViewChange` type\n * documents and enforces this via the type system.\n */\nexport type ViewChange =\n | AddViewChange\n | RemoveViewChange\n | ChildViewChange\n | EditViewChange;\n\nexport type RowOnlyNode = {row: Row};\n\nexport type AddViewChange = {\n type: 'add';\n node: ViewNode;\n};\n\nexport type RemoveViewChange = {\n type: 'remove';\n node: ViewNode;\n};\n\ntype ChildViewChange = {\n type: 'child';\n node: RowOnlyNode;\n child: {\n relationshipName: string;\n change: ViewChange;\n };\n};\n\ntype EditViewChange = {\n type: 'edit';\n node: RowOnlyNode;\n oldNode: RowOnlyNode;\n};\n\n/**\n * This is a subset of WeakMap but restricted to what we need.\n * @deprecated Not used anymore. This will be removed in the future.\n */\nexport interface RefCountMap {\n get(entry: Entry): number | undefined;\n set(entry: Entry, refCount: number): void;\n delete(entry: Entry): boolean;\n}\n\n/**\n * Get child nodes from a relationship, handling both lazy (Node) and expanded (ExpandedNode).\n */\nfunction getChildNodes(\n node: ViewNode,\n relationship: string,\n): Iterable<ViewNode> {\n const children = node.relationships[relationship];\n if (Array.isArray(children)) {\n // ExpandedNode: already an array\n return children;\n }\n // Node: lazy generator function\n return skipYields(children());\n}\n\ntype Mutate = boolean;\ntype WithIDs = boolean;\n\n/**\n * Transaction-scoped copy-on-write.\n *\n * `applyChange` is immutable: it path-copies a new spine on every call so the\n * previously-emitted snapshot is never mutated. But within a single transaction\n * (a run of `push()` calls before `flush()`) only the final state is ever\n * observed by a listener, so the intermediate spines are pure allocation/GC\n * churn — making a K-change transaction O(K * spineSize).\n *\n * When the caller passes a WeakSet as the `mutate` argument, objects and arrays\n * that were created or cloned during the current transaction are recorded in it.\n * A helper that needs to modify such an object mutates it in place (it is not\n * yet observed) instead of cloning again. The first touch of a node still\n * copies-on-write (preserving the committed snapshot's references); subsequent\n * touches in the same transaction are in-place. This brings a K-change\n * transaction to O(spineSize + K) while keeping cross-transaction reference\n * stability.\n *\n * The set is module-scoped for the duration of a single (synchronous,\n * non-re-entrant) `applyChange` call and saved/restored around it.\n *\n * It is a WeakSet on purpose: it must not keep transiently-cloned arrays/entries\n * alive. A strong Set would extend their lifetime to the end of the transaction,\n * pushing large clones out of the young generation and adding GC pressure that\n * shows up as a regression on single-change transactions over wide lists. A\n * WeakSet gives the same identity test (\"created this transaction?\") while\n * letting dead clones be collected as cheaply as in the plain immutable path.\n */\nlet activeDirty: WeakSet<object> | undefined;\n\n/** True if `o` was created/cloned during the current transaction. */\nfunction owns(o: object): boolean {\n return activeDirty !== undefined && activeDirty.has(o);\n}\n\n/** Record `o` as owned by the current transaction (no-op outside a txn). */\nfunction track<T extends object>(o: T): T {\n activeDirty?.add(o);\n return o;\n}\n\n/**\n * Immutable view update. Returns new Entry on change, same Entry if unchanged.\n * Unchanged entries keep identity, enabling shallow comparison optimizations\n * in UI frameworks (React.memo, Solid's fine-grained reactivity, etc).\n *\n * Propagation: recurse DOWN to find target, copy objects on the way UP.\n * Siblings keep original refs. Only the ancestor path is copied.\n *\n * root {users:[A,B], items:[C,D,E]} --edit C--> root' {users:[A,B], items':[C',D,E]}\n * │ same ref │ │ │\n * └─────────────────┴── unchanged ──────────────┘ new array C' new, D/E same\n *\n * `mutate` selects the update strategy:\n * - `false` (default): fully immutable; every changed node is path-copied.\n * - `true`: mutate the tree in place (only safe when it is not yet observed,\n * e.g. during initial hydration).\n * - a `WeakSet`: transaction-scoped copy-on-write — copy on first touch, then\n * mutate in place for the rest of the transaction. See `activeDirty` above.\n */\nexport function applyChange(\n parentEntry: Entry,\n change: ViewChange,\n schema: SourceSchema,\n relationship: string,\n format: Format,\n withIDs = false,\n mutate: boolean | WeakSet<object> = false,\n): Entry {\n // A WeakSet selects copy-on-write; a boolean selects full mutate / immutable.\n const inPlace = mutate === true;\n const prevDirty = activeDirty;\n activeDirty = typeof mutate === 'object' ? mutate : undefined;\n try {\n return applyChangeInternal(\n parentEntry as MetaEntry<typeof inPlace>,\n change,\n schema,\n relationship,\n format,\n withIDs,\n inPlace,\n );\n } finally {\n activeDirty = prevDirty;\n }\n}\n\nexport function applyChangeInternal<M extends Mutate>(\n parentEntry: MetaEntry<M>,\n change: ViewChange,\n schema: SourceSchema,\n relationship: string,\n format: Format,\n withIDs: WithIDs,\n mutate: M,\n): MetaEntry<M> {\n if (schema.isHidden) {\n switch (change.type) {\n case 'add':\n case 'remove': {\n let currentParent = parentEntry;\n for (const relationship of Object.keys(change.node.relationships)) {\n const childSchema = must(schema.relationships[relationship]);\n for (const node of getChildNodes(change.node, relationship)) {\n currentParent = applyChangeInternal(\n currentParent,\n {type: change.type, node},\n childSchema,\n relationship,\n format,\n withIDs,\n mutate,\n );\n }\n }\n return currentParent;\n }\n case 'edit':\n // If hidden at this level it means that the hidden row was changed. If\n // the row was changed in such a way that it would change the\n // relationships then the edit would have been split into remove and\n // add.\n return parentEntry;\n case 'child': {\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n return applyChangeInternal(\n parentEntry,\n change.child.change,\n childSchema,\n relationship,\n format,\n withIDs,\n mutate,\n );\n }\n default:\n unreachable(change);\n }\n }\n\n const {singular, relationships: childFormats} = format;\n switch (change.type) {\n // ADD: Insert row (rc=1) or increment refCount if duplicate.\n // RefCount tracks when the same row is reachable via multiple edges\n // within a relationship:\n //\n // issue.labels: [L1, L2] both point to same creator\n // │ │ │\n // ▼ ▼ ▼\n // label.creator ──────────► [User:rc=2] (one row, two refs)\n //\n // add(A) add(A) remove(A) remove(A)\n // ↓ ↓ ↓ ↓\n // [A:rc=1] → [A:rc=2] → [A:rc=1] → (deleted)\n case 'add': {\n if (singular) {\n const oldEntry = getOptionalSingularEntry(parentEntry, relationship);\n if (oldEntry !== undefined) {\n // Duplicate add: increment refCount\n assert(\n schema.compareRows(oldEntry, change.node.row) === 0,\n `Singular relationship '${relationship}' should not have multiple rows. You may need to declare this relationship with the \\`many\\` helper instead of the \\`one\\` helper in your schema.`,\n );\n\n const newEntry = incRefCount(mutate, oldEntry);\n return setRelation(mutate, parentEntry, relationship, newEntry);\n } else {\n // New row: create with rc=1, initialize nested relationships\n const newEntry = makeNewMetaEntry(\n change.node.row,\n schema,\n withIDs,\n 1,\n );\n initializeRelationshipsForNewEntryIfAny(\n newEntry,\n change.node,\n schema,\n childFormats,\n withIDs,\n );\n return setRelation(mutate, parentEntry, relationship, newEntry);\n }\n } else {\n // Plural: binary search for position, insert or increment refCount\n const view = getChildEntryList(parentEntry, relationship);\n const {newEntry, newView} = add(\n change.node.row,\n view,\n schema,\n withIDs,\n mutate,\n );\n\n if (newEntry) {\n initializeRelationshipsForNewEntryIfAny(\n newEntry,\n change.node,\n schema,\n childFormats,\n withIDs,\n );\n }\n return setRelation(mutate, parentEntry, relationship, newView);\n }\n }\n // REMOVE: Decrement refCount, physically remove when rc=0.\n case 'remove': {\n if (singular) {\n const oldEntry = getSingularEntry(parentEntry, relationship);\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n return setRelation(mutate, parentEntry, relationship, undefined);\n }\n const newEntry = decRefCount(mutate, oldEntry);\n return setRelation(mutate, parentEntry, relationship, newEntry);\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n const newView = removeAndUpdateRefCount(\n view,\n change.node.row,\n schema.compareRows,\n mutate,\n );\n return setRelation(mutate, parentEntry, relationship, newView);\n }\n }\n // CHILD: Propagate nested change up to this level (leaf-to-root pattern).\n case 'child': {\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n const childFormat = format.relationships[change.child.relationshipName];\n if (childFormat === undefined) {\n return parentEntry; // Relationship not in view format\n }\n\n if (singular) {\n const existing = getSingularEntry(parentEntry, relationship);\n const newExisting = applyChangeInternal(\n existing,\n change.child.change,\n childSchema,\n change.child.relationshipName,\n childFormat,\n withIDs,\n mutate,\n );\n // Preserve identity if child didn't change (enables shallow-compare optimizations).\n if (newExisting === existing) {\n return parentEntry;\n }\n return setRelation(mutate, parentEntry, relationship, newExisting);\n } else {\n // Find the target row in the sorted array via binary search.\n const view = getChildEntryList(parentEntry, relationship);\n const pos = binarySearch(view, change.node.row, schema.compareRows);\n assert(pos >= 0, 'node does not exist');\n const existing = view[pos];\n const newExisting = applyChangeInternal(\n existing,\n change.child.change,\n childSchema,\n change.child.relationshipName,\n childFormat,\n withIDs,\n mutate,\n );\n // Preserve identity if descendant didn't change.\n if (newExisting === existing) {\n return parentEntry;\n }\n // applyChangeInternal preserves MetaEntry structure when input is MetaEntry\n assertMetaEntry(newExisting);\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n arrayWith(mutate, view, pos, newExisting),\n );\n }\n }\n // EDIT: Update row fields. If sort key changes, row may move position.\n //\n // Position change with rc>1 (two query paths reach same row):\n //\n // Before: [A, B(rc=2), C, D] After: [A, B(rc=1), C, B'(rc=1), D]\n // │ │ │\n // path1 + path2 path1 ghost path2 moved\n //\n // Why ghost stays: path1 still expects B at old position.\n // B' appears where path2's sort order places it.\n case 'edit': {\n if (singular) {\n const existing = getSingularEntry(parentEntry, relationship);\n const newEntry = applyEdit(existing, change, schema, withIDs, mutate);\n return setRelation(mutate, parentEntry, relationship, newEntry);\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n // Sort key changed: row may need to move\n if (schema.compareRows(change.oldNode.row, change.node.row) !== 0) {\n const oldPos = binarySearch(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n assert(oldPos >= 0, 'old node does not exist');\n const oldEntry = view[oldPos];\n const rawPos = binarySearch(\n view,\n change.node.row,\n schema.compareRows,\n );\n const found = rawPos >= 0;\n const pos = found ? rawPos : ~rawPos;\n // A special case:\n // when refCount is 1 (so the row is being moved without leaving a\n // placeholder behind), and the new pos is the same as the old, or\n // directly after the old (so after the remove of the old it would be\n // in the same pos): the row does not need to be moved, just edited.\n if (\n oldEntry[refCountSymbol] === 1 &&\n (pos === oldPos || pos - 1 === oldPos)\n ) {\n const newEntry = applyEdit(\n oldEntry,\n change,\n schema,\n withIDs,\n mutate,\n );\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n arrayWith(mutate, view, oldPos, newEntry),\n );\n } else {\n // Move the row. If rc > 1, an edit will be received for each ref.\n // On first edit: move row, apply edit, set rc=1. Leave a copy at\n // old pos with decremented rc. As each edit arrives, old copy's rc\n // decrements and new pos rc increments. When copy rc hits 0, remove.\n const newRefCount = oldEntry[refCountSymbol] - 1;\n let newView: MutableMetaEntryList;\n let adjustedPos = pos;\n\n if (newRefCount === 0) {\n newView = removeAt(mutate, view, oldPos);\n adjustedPos = oldPos < pos ? pos - 1 : pos;\n } else {\n const oldEntryCopy = setRefCount(mutate, oldEntry, newRefCount);\n newView = arrayWith(mutate, view, oldPos, oldEntryCopy);\n }\n\n if (found) {\n // Merge with existing at new pos\n const existingEntry = newView[adjustedPos];\n const editedEntry = applyEdit(\n existingEntry,\n change,\n schema,\n withIDs,\n mutate,\n );\n const updatedEntry = setRefCount(\n mutate,\n editedEntry,\n existingEntry[refCountSymbol] + 1,\n );\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n arrayWith(mutate, newView, adjustedPos, updatedEntry),\n );\n } else {\n // Insert at new pos with rc=1\n const editedEntry = applyEdit(\n oldEntry,\n change,\n schema,\n withIDs,\n mutate,\n );\n const movedEntry = setRefCount(mutate, editedEntry, 1);\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n insertAt(mutate, newView, adjustedPos, movedEntry),\n );\n }\n }\n } else {\n // Sort key unchanged: edit in place\n const pos = binarySearch(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n assert(pos >= 0, 'node does not exist');\n const newEntry = applyEdit(\n view[pos],\n change,\n schema,\n withIDs,\n mutate,\n );\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n arrayWith(mutate, view, pos, newEntry),\n );\n }\n }\n }\n default:\n unreachable(change);\n }\n}\n\n/**\n * Batch apply multiple changes to an Entry tree.\n * For small batches or complex cases, falls back to sequential applyChange.\n * Future optimization: O(N + K) batch processing for large K.\n */\nexport function applyChanges(\n parentEntry: Entry,\n changes: ViewChange[],\n schema: SourceSchema,\n relationship: string,\n format: Format,\n withIDs: WithIDs = false,\n mutate: Mutate = false,\n): Entry {\n let result = parentEntry;\n for (const change of changes) {\n result = applyChange(\n result,\n change,\n schema,\n relationship,\n format,\n withIDs,\n mutate,\n );\n }\n return result;\n}\n\nfunction applyEdit<M extends Mutate>(\n existing: MetaEntry<M>,\n change: EditViewChange,\n schema: SourceSchema,\n withIDs: WithIDs,\n mutate: Mutate,\n): MetaEntry<M> {\n // In-place edit is safe when fully mutating or when `existing` was already\n // created/cloned in this transaction (copy-on-write). A primary-key change\n // always needs a fresh entry so identity tracks the new key.\n const canMutate = mutate || owns(existing);\n const newEntry: MutableMetaEntry =\n canMutate && schema.compareRows(change.oldNode.row, change.node.row) === 0\n ? Object.assign(existing, change.node.row)\n : track({...existing, ...change.node.row});\n\n if (withIDs) {\n return setProperty(\n mutate,\n newEntry,\n idSymbol,\n makeID(change.node.row, schema),\n );\n }\n return newEntry;\n}\n\n/**\n * Initialize child relationships on a newly-added entry by mutating it in place.\n *\n * New nodes don't exist in the view yet, so we can build in-place (no refs to preserve):\n *\n * New nodes don't exist in the view yet, so we can build in-place (no refs to preserve):\n *\n * Existing node edit (must path-copy): New node (can build in-place):\n *\n * view: [A, B, C] view: [A, B, _]\n * │ │\n * edit C.child add C with children\n * │ │\n * ▼ ▼\n * view': [A, B, C'] ◄─ path-copy view': [A, B, C{children:[...]}]\n * up the tree └─ built in-place\n *\n * Hidden schemas still use applyChange to collapse junction levels.\n */\nfunction initializeRelationshipsForNewEntryIfAny(\n entry: MutableMetaEntry,\n node: ViewNode,\n schema: SourceSchema,\n childFormats: Record<string, Format>,\n withIDs: WithIDs,\n): void {\n let result = entry;\n for (const relationship of Object.keys(node.relationships)) {\n const childSchema = must(schema.relationships[relationship]);\n const childFormat = childFormats[relationship];\n if (childFormat === undefined) {\n continue;\n }\n\n // Hidden/singular: use applyChange to handle properly\n if (childSchema.isHidden || childFormat.singular) {\n const newView = childFormat.singular\n ? undefined\n : track([] as MutableMetaEntryList);\n result[relationship] = newView;\n\n for (const childNode of getChildNodes(node, relationship)) {\n applyChangeInternal(\n result,\n {type: 'add', node: childNode},\n childSchema,\n relationship,\n childFormat,\n withIDs,\n true, // this is a new entry, so we can mutate\n );\n }\n } else {\n // Plural non-hidden: build array in-place for efficiency\n const childArray: MutableMetaEntryList = track([]);\n\n for (const childNode of getChildNodes(node, relationship)) {\n const newEntry = makeNewMetaEntry(\n childNode.row,\n childSchema,\n withIDs,\n 1,\n );\n const rawPos = binarySearch(\n childArray,\n childNode.row,\n childSchema.compareRows,\n );\n\n if (rawPos >= 0) {\n childArray[rawPos][refCountSymbol]++;\n } else {\n childArray.splice(~rawPos, 0, newEntry);\n initializeRelationshipsForNewEntryIfAny(\n newEntry,\n childNode,\n childSchema,\n childFormat.relationships,\n withIDs,\n );\n }\n }\n\n result[relationship] = childArray;\n }\n }\n}\n\nfunction add<M extends Mutate>(\n row: Row,\n view: MetaEntryList<M>,\n schema: SourceSchema,\n withIDs: WithIDs,\n mutate: M,\n): {\n newEntry: MutableMetaEntry | undefined;\n newView: MutableMetaEntryList;\n} {\n const rawPos = binarySearch(view, row, schema.compareRows);\n\n if (rawPos >= 0) {\n const existing = view[rawPos];\n\n const updated = incRefCount(mutate, existing);\n return {\n newEntry: undefined,\n newView: arrayWith(mutate, view, rawPos, updated),\n };\n }\n const newEntry = makeNewMetaEntry(row, schema, withIDs, 1);\n return {newEntry, newView: insertAt(mutate, view, ~rawPos, newEntry)};\n}\n\nfunction insertAt<M extends Mutate, T>(\n mutate: M,\n array: MutableArray<M, T>,\n index: number,\n item: T,\n): T[] {\n if (mutate || owns(array)) {\n (array as T[]).splice(index, 0, item);\n return array as T[];\n }\n return track(array.toSpliced(index, 0, item));\n}\n\nfunction removeAt<M extends Mutate, T>(\n mutate: M,\n array: MutableArray<M, T>,\n index: number,\n): T[] {\n if (mutate || owns(array)) {\n (array as T[]).splice(index, 1);\n return array as T[];\n }\n return track(array.toSpliced(index, 1));\n}\n\nfunction removeAndUpdateRefCount<M extends Mutate>(\n view: MetaEntryList<M>,\n row: Row,\n compareRows: Comparator,\n mutate: M,\n): MutableMetaEntryList {\n const pos = binarySearch(view, row, compareRows);\n assert(pos >= 0, 'node does not exist');\n const oldEntry = view[pos];\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n return removeAt(mutate, view, pos);\n }\n const newEntry = decRefCount(mutate, oldEntry);\n return arrayWith(mutate, view, pos, newEntry);\n}\n\n/**\n * Binary search returning a number.\n * - If found at index `i`: returns `i` (>= 0).\n * - If not found, insertion point is `low`: returns `~low` (< 0).\n * Recover insertion point with `~result`.\n */\nfunction binarySearch(\n view: MetaEntryList<Mutate>,\n target: Row,\n comparator: Comparator,\n): number {\n let high = view.length - 1;\n if (high < 0) {\n return ~0;\n }\n\n // Probe the last entry before searching. Hydration feeds the view rows in\n // the query's sort order, so every insert belongs at the end and the plain\n // search spends log2(n) comparisons to rediscover that -- about eleven per\n // row for a view of a couple of thousand. Row comparison is the single\n // largest cost in hydration on Hermes, so collapsing those eleven to one is\n // worth the one extra comparison this costs when the row does land inside\n // the view, which is a single push rather than a bulk load.\n // MetaEntry has all Row props; comparator only reads string keys\n const last = comparator(view[high] as Row, target);\n if (last < 0) {\n return ~(high + 1);\n }\n if (last === 0) {\n return high;\n }\n\n let low = 0;\n high -= 1;\n while (low <= high) {\n const mid = (low + high) >>> 1;\n const comparison = comparator(view[mid] as Row, target);\n if (comparison < 0) {\n low = mid + 1;\n } else if (comparison > 0) {\n high = mid - 1;\n } else {\n return mid;\n }\n }\n return ~low;\n}\n\n/** Assert value is MetaEntry (has refCountSymbol). */\nfunction assertMetaEntry<M extends Mutate>(\n v: unknown,\n): asserts v is MetaEntry<M> {\n assertNumber((v as Partial<MetaEntry<M>>)[refCountSymbol]);\n}\n\n/** Get singular MetaEntry, throws if missing. */\nfunction getSingularEntry<M extends Mutate>(\n parentEntry: MetaEntry<M>,\n relationship: string,\n): MetaEntry<M> {\n const entry = parentEntry[relationship];\n assert(entry !== undefined, 'node does not exist');\n assertMetaEntry(entry);\n return entry;\n}\n\n/** Get singular MetaEntry or undefined if not set. */\nfunction getOptionalSingularEntry<M extends Mutate>(\n parentEntry: MetaEntry<M>,\n relationship: string,\n): MetaEntry<M> | undefined {\n const entry = parentEntry[relationship];\n if (entry === undefined) {\n return undefined;\n }\n assertMetaEntry(entry);\n return entry;\n}\n\n/** Get child array as MetaEntryList. */\nfunction getChildEntryList<M extends Mutate>(\n parentEntry: MetaEntry<M>,\n relationship: string,\n): MetaEntryList<M> {\n const view = parentEntry[relationship];\n // `relationship` is a string key, so a name colliding with a column would\n // put a row value here; the message must not repeat it back.\n assert(Array.isArray(view), 'expected relationship array');\n return view as MetaEntryList<M>;\n}\n\n/** Create MetaEntry from row with given refCount. */\nfunction makeNewMetaEntry(\n row: Row,\n schema: SourceSchema,\n withIDs: WithIDs,\n rc: number,\n): MutableMetaEntry {\n // This creates a new MetaEntry from a Row. We never mutate Rows.\n if (withIDs) {\n return track({\n ...row,\n [refCountSymbol]: rc,\n [idSymbol]: makeID(row, schema),\n });\n }\n return track({\n ...row,\n [refCountSymbol]: rc,\n });\n}\n\nfunction makeID(row: Row, schema: SourceSchema) {\n // optimization for case of non-compound primary key\n if (schema.primaryKey.length === 1) {\n return JSON.stringify(row[schema.primaryKey[0]]);\n }\n return JSON.stringify(schema.primaryKey.map(k => row[k]));\n}\n\nfunction incRefCount<M extends Mutate>(\n mutate: M,\n entry: MetaEntry<M>,\n): MutableMetaEntry {\n return setRefCount(mutate, entry, entry[refCountSymbol] + 1);\n}\n\nfunction decRefCount<M extends Mutate>(\n mutate: M,\n entry: MetaEntry<M>,\n): MutableMetaEntry {\n return setRefCount(mutate, entry, entry[refCountSymbol] - 1);\n}\n\nfunction setRefCount<M extends Mutate>(\n mutate: M,\n entry: MetaEntry<M>,\n count: number,\n): MutableMetaEntry {\n if (mutate || owns(entry)) {\n (entry as MutableMetaEntry)[refCountSymbol] = count;\n return entry;\n }\n return track({\n ...entry,\n [refCountSymbol]: count,\n });\n}\n\nfunction arrayWith<M extends Mutate, T>(\n mutate: M,\n array: MutableArray<M, T>,\n index: number,\n value: T,\n): T[] {\n if (mutate || owns(array)) {\n (array as T[])[index] = value;\n return array as T[];\n }\n return track(array.with(index, value));\n}\n\nfunction setProperty<\n M extends Mutate,\n K extends string | keyof MetaEntry<M>,\n V,\n>(\n mutate: M,\n parentEntry: MetaEntry<M>,\n key: K,\n value: V,\n): MutableMetaEntry & {[P in K]: V} {\n if (mutate || owns(parentEntry)) {\n assignProperty(parentEntry as {[P in K]: V}, key, value);\n return parentEntry as MutableMetaEntry & {[P in K]: V};\n }\n return track({\n ...parentEntry,\n [key]: value,\n }) as MutableMetaEntry & {[P in K]: V};\n}\n\nconst setRelation: <M extends Mutate>(\n mutate: M,\n parentEntry: MetaEntry<M>,\n relationship: string,\n value: Entry | Entry[] | undefined,\n) => MutableMetaEntry = setProperty;\n"],"mappings":"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"}
@@ -58,12 +58,35 @@ export interface Row {
58
58
  }
59
59
  export interface DBConnection<TWrappedTransaction> {
60
60
  transaction: <T>(cb: (tx: DBTransaction<TWrappedTransaction>) => Promise<T>) => Promise<T>;
61
+ /**
62
+ * Executes a single SQL statement on the connection without opening,
63
+ * committing, or rolling back a transaction of its own. With a pooled
64
+ * handle this is a plain autocommit statement. With a single dedicated
65
+ * connection, driver semantics apply: a `pg` `Client` queues it behind, and
66
+ * inside, whatever transaction is open on that connection, while postgres.js
67
+ * waits for the reserved connection to be released.
68
+ *
69
+ * Optional. When present, `ZQLDatabase.run` uses it for single-statement
70
+ * reads instead of `transaction`, so no `BEGIN`/`COMMIT` round-trips are
71
+ * needed and any setup done inside `transaction` does not apply to those
72
+ * reads. Custom adapters must implement this to get that behavior; when
73
+ * absent, `ZQLDatabase.run` falls back to `transaction`.
74
+ */
75
+ query?: Queryable['query'] | undefined;
76
+ /**
77
+ * Mirrors {@linkcode DBTransaction.runQuery} for reads issued through
78
+ * {@linkcode query}. An adapter that customizes `DBTransaction.runQuery`
79
+ * should implement this too so that `ZQLDatabase.run` and `tx.run` execute
80
+ * a query the same way. Optional; when absent, the default Postgres
81
+ * executor is used.
82
+ */
83
+ runQuery?: DBTransaction<TWrappedTransaction>['runQuery'] | undefined;
61
84
  }
62
85
  export interface DBTransaction<T> extends Queryable {
63
86
  readonly wrappedTransaction: T;
64
87
  runQuery<TReturn>(ast: AST, format: Format, schema: Schema, serverSchema: ServerSchema): Promise<HumanReadable<TReturn>>;
65
88
  }
66
- interface Queryable {
89
+ export interface Queryable {
67
90
  query: (query: string, args: unknown[]) => Promise<Iterable<Row>>;
68
91
  }
69
92
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"custom.d.ts","sourceRoot":"","sources":["../../../../../zql/src/mutate/custom.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"custom.d.ts","sourceRoot":"","sources":["../../../../../zql/src/mutate/custom.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"custom.js","names":[],"sources":["../../../../../zql/src/mutate/custom.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport type {AST} from '../../../zero-protocol/src/ast.ts';\nimport type {\n DefaultSchema,\n DefaultWrappedTransaction,\n} from '../../../zero-types/src/default-types.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {ServerSchema} from '../../../zero-types/src/server-schema.ts';\nimport type {Format} from '../ivm/view.ts';\nimport type {HumanReadable, Query, RunOptions} from '../query/query.ts';\nimport type {ConditionalSchemaQuery} from '../query/schema-query.ts';\nimport type {CRUDMutateRequest, SchemaCRUD, TransactionMutate} from './crud.ts';\n\ntype ClientID = string;\n\n/**\n * A base transaction interface that any Transaction<S, T> is assignable to.\n * Used in places where the schema type doesn't need to be preserved,\n * like the public signature of Mutator.fn.\n */\nexport interface AnyTransaction {\n readonly location: Location;\n readonly clientID: string;\n readonly mutationID: number;\n readonly reason: TransactionReason;\n}\n\nexport type Location = 'client' | 'server';\nexport type TransactionReason = 'optimistic' | 'rebase' | 'authoritative';\n\nexport interface TransactionBase<S extends Schema> {\n readonly location: Location;\n readonly clientID: ClientID;\n /**\n * The ID of the mutation that is being applied.\n */\n readonly mutationID: number;\n\n /**\n * The reason for the transaction.\n */\n readonly reason: TransactionReason;\n\n readonly mutate: TransactionMutate<S>;\n /**\n * @deprecated Use {@linkcode createBuilder} with `tx.run(zql.table.where(...))` instead.\n */\n readonly query: ConditionalSchemaQuery<S>;\n\n run<TTable extends keyof S['tables'] & string, TReturn>(\n query: Query<TTable, S, TReturn>,\n options?: RunOptions,\n ): Promise<HumanReadable<TReturn>>;\n}\n\nexport type Transaction<\n S extends Schema = DefaultSchema,\n TWrappedTransaction = DefaultWrappedTransaction,\n> = ServerTransaction<S, TWrappedTransaction> | ClientTransaction<S>;\n\nexport interface ServerTransaction<\n S extends Schema = DefaultSchema,\n TWrappedTransaction = DefaultWrappedTransaction,\n> extends TransactionBase<S> {\n readonly location: 'server';\n readonly reason: 'authoritative';\n readonly dbTransaction: DBTransaction<TWrappedTransaction>;\n}\n\n/**\n * An instance of this is passed to custom mutator implementations and\n * allows reading and writing to the database and IVM at the head at which the\n * mutator is being applied.\n */\nexport interface ClientTransaction<\n S extends Schema = DefaultSchema,\n> extends TransactionBase<S> {\n readonly location: 'client';\n readonly reason: 'optimistic' | 'rebase';\n}\n\nexport interface Row {\n [column: string]: unknown;\n}\n\nexport interface DBConnection<TWrappedTransaction> {\n transaction: <T>(\n cb: (tx: DBTransaction<TWrappedTransaction>) => Promise<T>,\n ) => Promise<T>;\n}\n\nexport interface DBTransaction<T> extends Queryable {\n readonly wrappedTransaction: T;\n runQuery<TReturn>(\n ast: AST,\n format: Format,\n schema: Schema,\n serverSchema: ServerSchema,\n ): Promise<HumanReadable<TReturn>>;\n}\n\ninterface Queryable {\n query: (query: string, args: unknown[]) => Promise<Iterable<Row>>;\n}\n\n/**\n * A callable mutate shape with optional table helpers used by helper factories\n * like `makeMutateCRUD`. Transactions expose `SchemaCRUD` instead of this type.\n */\nexport type MutateCRUD<S extends Schema, AddSchemaCRUD extends boolean> = {\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n (request: CRUDMutateRequest<S, any, any, any>): Promise<void>;\n} & (AddSchemaCRUD extends true ? SchemaCRUD<S> : {});\n\nexport function customMutatorKey(sep: string, parts: string[]) {\n for (const part of parts) {\n assert(\n !part.includes(sep),\n `mutator names/namespaces must not include a ${sep}`,\n );\n }\n return parts.join(sep);\n}\n"],"mappings":";;AAkHA,SAAgB,iBAAiB,KAAa,OAAiB;CAC7D,KAAK,MAAM,QAAQ,OACjB,OACE,CAAC,KAAK,SAAS,GAAG,GAClB,+CAA+C,KACjD;CAEF,OAAO,MAAM,KAAK,GAAG;AACvB"}
1
+ {"version":3,"file":"custom.js","names":[],"sources":["../../../../../zql/src/mutate/custom.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport type {AST} from '../../../zero-protocol/src/ast.ts';\nimport type {\n DefaultSchema,\n DefaultWrappedTransaction,\n} from '../../../zero-types/src/default-types.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {ServerSchema} from '../../../zero-types/src/server-schema.ts';\nimport type {Format} from '../ivm/view.ts';\nimport type {HumanReadable, Query, RunOptions} from '../query/query.ts';\nimport type {ConditionalSchemaQuery} from '../query/schema-query.ts';\nimport type {CRUDMutateRequest, SchemaCRUD, TransactionMutate} from './crud.ts';\n\ntype ClientID = string;\n\n/**\n * A base transaction interface that any Transaction<S, T> is assignable to.\n * Used in places where the schema type doesn't need to be preserved,\n * like the public signature of Mutator.fn.\n */\nexport interface AnyTransaction {\n readonly location: Location;\n readonly clientID: string;\n readonly mutationID: number;\n readonly reason: TransactionReason;\n}\n\nexport type Location = 'client' | 'server';\nexport type TransactionReason = 'optimistic' | 'rebase' | 'authoritative';\n\nexport interface TransactionBase<S extends Schema> {\n readonly location: Location;\n readonly clientID: ClientID;\n /**\n * The ID of the mutation that is being applied.\n */\n readonly mutationID: number;\n\n /**\n * The reason for the transaction.\n */\n readonly reason: TransactionReason;\n\n readonly mutate: TransactionMutate<S>;\n /**\n * @deprecated Use {@linkcode createBuilder} with `tx.run(zql.table.where(...))` instead.\n */\n readonly query: ConditionalSchemaQuery<S>;\n\n run<TTable extends keyof S['tables'] & string, TReturn>(\n query: Query<TTable, S, TReturn>,\n options?: RunOptions,\n ): Promise<HumanReadable<TReturn>>;\n}\n\nexport type Transaction<\n S extends Schema = DefaultSchema,\n TWrappedTransaction = DefaultWrappedTransaction,\n> = ServerTransaction<S, TWrappedTransaction> | ClientTransaction<S>;\n\nexport interface ServerTransaction<\n S extends Schema = DefaultSchema,\n TWrappedTransaction = DefaultWrappedTransaction,\n> extends TransactionBase<S> {\n readonly location: 'server';\n readonly reason: 'authoritative';\n readonly dbTransaction: DBTransaction<TWrappedTransaction>;\n}\n\n/**\n * An instance of this is passed to custom mutator implementations and\n * allows reading and writing to the database and IVM at the head at which the\n * mutator is being applied.\n */\nexport interface ClientTransaction<\n S extends Schema = DefaultSchema,\n> extends TransactionBase<S> {\n readonly location: 'client';\n readonly reason: 'optimistic' | 'rebase';\n}\n\nexport interface Row {\n [column: string]: unknown;\n}\n\nexport interface DBConnection<TWrappedTransaction> {\n transaction: <T>(\n cb: (tx: DBTransaction<TWrappedTransaction>) => Promise<T>,\n ) => Promise<T>;\n\n /**\n * Executes a single SQL statement on the connection without opening,\n * committing, or rolling back a transaction of its own. With a pooled\n * handle this is a plain autocommit statement. With a single dedicated\n * connection, driver semantics apply: a `pg` `Client` queues it behind, and\n * inside, whatever transaction is open on that connection, while postgres.js\n * waits for the reserved connection to be released.\n *\n * Optional. When present, `ZQLDatabase.run` uses it for single-statement\n * reads instead of `transaction`, so no `BEGIN`/`COMMIT` round-trips are\n * needed and any setup done inside `transaction` does not apply to those\n * reads. Custom adapters must implement this to get that behavior; when\n * absent, `ZQLDatabase.run` falls back to `transaction`.\n */\n query?: Queryable['query'] | undefined;\n\n /**\n * Mirrors {@linkcode DBTransaction.runQuery} for reads issued through\n * {@linkcode query}. An adapter that customizes `DBTransaction.runQuery`\n * should implement this too so that `ZQLDatabase.run` and `tx.run` execute\n * a query the same way. Optional; when absent, the default Postgres\n * executor is used.\n */\n runQuery?: DBTransaction<TWrappedTransaction>['runQuery'] | undefined;\n}\n\nexport interface DBTransaction<T> extends Queryable {\n readonly wrappedTransaction: T;\n runQuery<TReturn>(\n ast: AST,\n format: Format,\n schema: Schema,\n serverSchema: ServerSchema,\n ): Promise<HumanReadable<TReturn>>;\n}\n\nexport interface Queryable {\n query: (query: string, args: unknown[]) => Promise<Iterable<Row>>;\n}\n\n/**\n * A callable mutate shape with optional table helpers used by helper factories\n * like `makeMutateCRUD`. Transactions expose `SchemaCRUD` instead of this type.\n */\nexport type MutateCRUD<S extends Schema, AddSchemaCRUD extends boolean> = {\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n (request: CRUDMutateRequest<S, any, any, any>): Promise<void>;\n} & (AddSchemaCRUD extends true ? SchemaCRUD<S> : {});\n\nexport function customMutatorKey(sep: string, parts: string[]) {\n for (const part of parts) {\n assert(\n !part.includes(sep),\n `mutator names/namespaces must not include a ${sep}`,\n );\n }\n return parts.join(sep);\n}\n"],"mappings":";;AA2IA,SAAgB,iBAAiB,KAAa,OAAiB;CAC7D,KAAK,MAAM,QAAQ,OACjB,OACE,CAAC,KAAK,SAAS,GAAG,GAClB,+CAA+C,KACjD;CAEF,OAAO,MAAM,KAAK,GAAG;AACvB"}
@@ -1 +1 @@
1
- {"version":3,"file":"mutator-registry.d.ts","sourceRoot":"","sources":["../../../../../zql/src/mutate/mutator-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mutator-registry.d.ts","sourceRoot":"","sources":["../../../../../zql/src/mutate/mutator-registry.ts"],"names":[],"mappings":"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"}
@@ -59,8 +59,8 @@ function createMutator(name, definition) {
59
59
  mutator["~"] = "Mutator";
60
60
  return mutator;
61
61
  }
62
- function* iterateMutators(registry) {
63
- yield* iterateLeaves(registry, isMutator);
62
+ function iterateMutators(registry) {
63
+ return iterateLeaves(registry, isMutator);
64
64
  }
65
65
  /**
66
66
  * Gets a Mutator by its dot-separated name from a MutatorRegistry.
@@ -1 +1 @@
1
- {"version":3,"file":"mutator-registry.js","names":[],"sources":["../../../../../zql/src/mutate/mutator-registry.ts"],"sourcesContent":["import {\n deepMerge,\n isPlainObject,\n type DeepMerge,\n} from '../../../shared/src/deep-merge.ts';\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {\n getValueAtPath,\n iterateLeaves,\n} from '../../../shared/src/object-traversal.ts';\nimport type {\n BaseDefaultSchema,\n DefaultSchema,\n} from '../../../zero-types/src/default-types.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport {validateInput} from '../query/validate-input.ts';\nimport type {Transaction} from './custom.ts';\nimport {\n isMutator,\n isMutatorDefinition,\n type AnyMutator,\n type AnyMutatorDefinition,\n type MutateRequest,\n type MutateRequestTypes,\n type Mutator,\n type MutatorDefinition,\n type MutatorExecutionFunction,\n type MutatorTypes,\n} from './mutator.ts';\n\n/**\n * Creates a MutatorRegistry from a tree of MutatorDefinitions,\n * optionally extending a base MutatorRegistry.\n *\n * @example\n * ```ts\n * // Create a new registry\n * const mutators = defineMutators({\n * user: {\n * create: defineMutator(...),\n * delete: defineMutator(...),\n * },\n * post: {\n * publish: defineMutator(...),\n * },\n * });\n *\n * // Extend an existing registry (e.g., for server-side overrides)\n * const serverMutators = defineMutators(mutators, {\n * user: {\n * create: defineMutator(...), // overrides mutators.user.create\n * },\n * // post.publish is inherited from mutators\n * });\n *\n * // Access mutators by path\n * const mr = mutators.user.create({name: 'Alice'});\n *\n * // Execute on client\n * zero.mutate(mr);\n *\n * // Execute on server\n * mr.mutator.fn({tx, ctx, args: mr.args});\n *\n * // Lookup by name (for server-side dispatch)\n * const mutator = getMutator(mutators, 'user.create');\n * ```\n */\nexport function defineMutators<\n // let MD infer freely so defaults aren't erased by a MutatorDefinitions constraint\n const MD,\n S extends BaseDefaultSchema = DefaultSchema,\n>(\n // we assert types here for clear error messages\n definitions: MD & AssertMutatorDefinitions<MD>,\n): MutatorRegistry<EnsureMutatorDefinitions<MD>, S>;\n\nexport function defineMutators<\n // same as MD above, but for TBase and TOverrides\n const TBase,\n const TOverrides,\n S extends BaseDefaultSchema = DefaultSchema,\n>(\n base:\n | MutatorRegistry<EnsureMutatorDefinitions<TBase>, S>\n | (TBase & AssertMutatorDefinitions<TBase>),\n overrides: TOverrides & AssertMutatorDefinitions<TOverrides>,\n): MutatorRegistry<\n DeepMerge<\n EnsureMutatorDefinitions<TBase>,\n EnsureMutatorDefinitions<TOverrides>,\n AnyMutatorDefinition\n >,\n S\n>;\n\nexport function defineMutators(\n definitionsOrBase: MutatorDefinitions | AnyMutatorRegistry,\n maybeOverrides?: MutatorDefinitions,\n): AnyMutatorRegistry {\n function processDefinitions(\n definitions: MutatorDefinitions,\n path: string[],\n ): Record<string | symbol, unknown> {\n const result: Record<string | symbol, unknown> = {\n ['~']: 'MutatorRegistry',\n };\n\n for (const [key, value] of Object.entries(definitions)) {\n path.push(key);\n const name = path.join('.');\n\n if (isMutatorDefinition(value)) {\n result[key] = createMutator(name, value);\n } else {\n // Nested definitions\n result[key] = processDefinitions(value, path);\n }\n path.pop();\n }\n\n return result;\n }\n\n if (maybeOverrides !== undefined) {\n // Merge base and overrides\n let base: Record<string | symbol, unknown>;\n if (!isMutatorRegistry(definitionsOrBase)) {\n base = processDefinitions(definitionsOrBase, []);\n } else {\n base = definitionsOrBase;\n }\n\n const processed = processDefinitions(maybeOverrides, []);\n\n const merged = deepMerge(base, processed, isMutatorLeaf);\n merged['~'] = 'MutatorRegistry';\n return merged as AnyMutatorRegistry;\n }\n\n return processDefinitions(\n definitionsOrBase as MutatorDefinitions,\n [],\n ) as AnyMutatorRegistry;\n}\n\nconst isMutatorLeaf = (value: unknown): boolean =>\n !isPlainObject(value) || isMutator(value);\n\n/**\n * Creates a function that can be used to define mutators with a specific schema.\n */\nexport function defineMutatorsWithType<\n TSchema extends Schema,\n>(): TypedDefineMutators<TSchema> {\n return defineMutators;\n}\n\n/**\n * The return type of defineMutatorsWithType. A function matching the\n * defineMutators overloads but with Schema pre-bound.\n */\ntype TypedDefineMutators<S extends Schema> = {\n // Single definitions\n <MD>(\n definitions: MD & AssertMutatorDefinitions<MD>,\n ): MutatorRegistry<EnsureMutatorDefinitions<MD>, S>;\n\n // Base and overrides\n <TBase, TOverrides>(\n base:\n | MutatorRegistry<EnsureMutatorDefinitions<TBase>, S>\n | (TBase & AssertMutatorDefinitions<TBase>),\n overrides: TOverrides,\n ): MutatorRegistry<\n DeepMerge<\n EnsureMutatorDefinitions<TBase>,\n EnsureMutatorDefinitions<TOverrides>,\n AnyMutatorDefinition\n >,\n S\n >;\n};\n\nexport type AssertMutatorDefinitions<MD> = MD extends MutatorDefinitions\n ? unknown\n : never;\n\nexport type EnsureMutatorDefinitions<MD> = MD extends MutatorDefinitions\n ? MD\n : never;\n\n/**\n * Checks if a value is a MutatorRegistry.\n */\nexport function isMutatorRegistry(value: unknown): value is AnyMutatorRegistry {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as Record<string, unknown>)['~'] === 'MutatorRegistry'\n );\n}\n\nexport type MutatorRegistryTypes<TSchema extends Schema> = 'MutatorRegistry' & {\n readonly $schema: TSchema;\n};\n\n/**\n * The result of defineMutators(). A tree of Mutators with a tag for detection.\n */\nexport type MutatorRegistry<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n> = ToMutatorTree<MD, TSchema> & {\n ['~']: MutatorRegistryTypes<TSchema>;\n};\n\n/**\n * A branded type for use in type constraints. Use this instead of\n * `MutatorRegistry<S, C, any>` to avoid TypeScript drilling into\n * the complex ToMutatorTree structure and hitting variance issues.\n */\nexport type AnyMutatorRegistry = {\n ['~']: MutatorRegistryTypes<Schema>;\n [key: string]: unknown;\n};\n\n/**\n * Transforms a MutatorDefinitions into a tree of Mutators.\n * Each MutatorDefinition becomes a Mutator at the same path.\n * Uses TInput for the callable args (TOutput is only used internally for validation).\n */\nexport type ToMutatorTree<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n> = {\n readonly [K in keyof MD]: MD[K] extends AnyMutatorDefinition\n ? // pull types from the phantom property\n Mutator<\n MD[K]['~']['$input'],\n TSchema,\n MD[K]['~']['$context'],\n MD[K]['~']['$wrappedTransaction']\n >\n : MD[K] extends MutatorDefinitions\n ? ToMutatorTree<MD[K], TSchema>\n : never;\n};\n\nexport type FromMutatorTree<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n> = {\n readonly [K in keyof MD]: MD[K] extends AnyMutatorDefinition\n ? // pull types from the phantom property\n Mutator<\n ReadonlyJSONValue | undefined, // intentionally left as generic to avoid variance issues\n TSchema,\n MD[K]['~']['$context'],\n MD[K]['~']['$wrappedTransaction']\n >\n : MD[K] extends MutatorDefinitions\n ? FromMutatorTree<MD[K], TSchema>\n : never;\n}[keyof MD];\n\n/**\n * A tree of MutatorDefinitions, possibly nested.\n */\nexport type MutatorDefinitions = {\n readonly [key: string]: AnyMutatorDefinition | MutatorDefinitions;\n};\n\nfunction createMutator<\n ArgsInput extends ReadonlyJSONValue | undefined,\n ArgsOutput extends ReadonlyJSONValue | undefined,\n TSchema extends Schema,\n C,\n TWrappedTransaction,\n>(\n name: string,\n definition: MutatorDefinition<ArgsInput, ArgsOutput, C, TWrappedTransaction>,\n): Mutator<ArgsInput, TSchema, C, TWrappedTransaction> {\n const {validator} = definition;\n\n // fn takes ReadonlyJSONValue args because it's called during rebase (from\n // stored JSON) and on the server (from wire format). Validation happens here.\n const fn: MutatorExecutionFunction<\n ArgsInput,\n C,\n Transaction<TSchema, TWrappedTransaction>\n > = async options => {\n const validatedArgs = validator\n ? validateInput(name, options.args, validator, 'mutator')\n : (options.args as unknown as ArgsOutput);\n await definition.fn({\n args: validatedArgs,\n ctx: options.ctx as C,\n tx: options.tx,\n });\n };\n\n const mutator = (\n args: ArgsInput,\n ): MutateRequest<ArgsInput, TSchema, C, TWrappedTransaction> => ({\n args,\n '~': 'MutateRequest' as MutateRequestTypes<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >,\n 'mutator': mutator as unknown as Mutator<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >,\n });\n\n mutator.mutatorName = name;\n mutator.fn = fn;\n mutator['~'] = 'Mutator' as unknown as MutatorTypes<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >;\n\n return mutator as unknown as Mutator<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >;\n}\n\nexport function* iterateMutators(\n registry: AnyMutatorRegistry,\n): Iterable<AnyMutator> {\n yield* iterateLeaves(registry, isMutator);\n}\n\n/**\n * Gets a Mutator by its dot-separated name from a MutatorRegistry.\n * Returns undefined if not found.\n */\nexport function getMutator<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n>(\n registry: MutatorRegistry<MD, TSchema>,\n name: string,\n): FromMutatorTree<MD, TSchema> | undefined {\n const m = getValueAtPath(registry, name, '.');\n return m as FromMutatorTree<MD, TSchema> | undefined;\n}\n\n/**\n * Gets a Mutator by its dot-separated name from a MutatorRegistry.\n * Throws if not found.\n */\nexport function mustGetMutator<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n>(\n registry: MutatorRegistry<MD, TSchema>,\n name: string,\n): FromMutatorTree<MD, TSchema> {\n const mutator = getMutator(registry, name);\n if (mutator === undefined) {\n throw new Error(`Mutator not found: ${name}`);\n }\n return mutator;\n}\n"],"mappings":";;;;;AAgGA,SAAgB,eACd,mBACA,gBACoB;CACpB,SAAS,mBACP,aACA,MACkC;EAClC,MAAM,SAA2C,GAC9C,MAAM,kBACT;EAEA,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,WAAW,GAAG;GACtD,KAAK,KAAK,GAAG;GACb,MAAM,OAAO,KAAK,KAAK,GAAG;GAE1B,IAAI,oBAAoB,KAAK,GAC3B,OAAO,OAAO,cAAc,MAAM,KAAK;QAGvC,OAAO,OAAO,mBAAmB,OAAO,IAAI;GAE9C,KAAK,IAAI;EACX;EAEA,OAAO;CACT;CAEA,IAAI,mBAAmB,KAAA,GAAW;EAEhC,IAAI;EACJ,IAAI,CAAC,kBAAkB,iBAAiB,GACtC,OAAO,mBAAmB,mBAAmB,CAAC,CAAC;OAE/C,OAAO;EAGT,MAAM,YAAY,mBAAmB,gBAAgB,CAAC,CAAC;EAEvD,MAAM,SAAS,UAAU,MAAM,WAAW,aAAa;EACvD,OAAO,OAAO;EACd,OAAO;CACT;CAEA,OAAO,mBACL,mBACA,CAAC,CACH;AACF;AAEA,IAAM,iBAAiB,UACrB,CAAC,cAAc,KAAK,KAAK,UAAU,KAAK;;;;AAK1C,SAAgB,yBAEkB;CAChC,OAAO;AACT;;;;AAuCA,SAAgB,kBAAkB,OAA6C;CAC7E,OACE,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,SAAS;AAEhD;AAwEA,SAAS,cAOP,MACA,YACqD;CACrD,MAAM,EAAC,cAAa;CAIpB,MAAM,KAIF,OAAM,YAAW;EACnB,MAAM,gBAAgB,YAClB,cAAc,MAAM,QAAQ,MAAM,WAAW,SAAS,IACrD,QAAQ;EACb,MAAM,WAAW,GAAG;GAClB,MAAM;GACN,KAAK,QAAQ;GACb,IAAI,QAAQ;EACd,CAAC;CACH;CAEA,MAAM,WACJ,UAC+D;EAC/D;EACA,KAAK;EAML,WAAW;CAMb;CAEA,QAAQ,cAAc;CACtB,QAAQ,KAAK;CACb,QAAQ,OAAO;CAOf,OAAO;AAMT;AAEA,UAAiB,gBACf,UACsB;CACtB,OAAO,cAAc,UAAU,SAAS;AAC1C;;;;;AAMA,SAAgB,WAId,UACA,MAC0C;CAE1C,OADU,eAAe,UAAU,MAAM,GAClC;AACT;;;;;AAMA,SAAgB,eAId,UACA,MAC8B;CAC9B,MAAM,UAAU,WAAW,UAAU,IAAI;CACzC,IAAI,YAAY,KAAA,GACd,MAAM,IAAI,MAAM,sBAAsB,MAAM;CAE9C,OAAO;AACT"}
1
+ {"version":3,"file":"mutator-registry.js","names":[],"sources":["../../../../../zql/src/mutate/mutator-registry.ts"],"sourcesContent":["import {\n deepMerge,\n isPlainObject,\n type DeepMerge,\n} from '../../../shared/src/deep-merge.ts';\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {\n getValueAtPath,\n iterateLeaves,\n} from '../../../shared/src/object-traversal.ts';\nimport type {\n BaseDefaultSchema,\n DefaultSchema,\n} from '../../../zero-types/src/default-types.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport {validateInput} from '../query/validate-input.ts';\nimport type {Transaction} from './custom.ts';\nimport {\n isMutator,\n isMutatorDefinition,\n type AnyMutator,\n type AnyMutatorDefinition,\n type MutateRequest,\n type MutateRequestTypes,\n type Mutator,\n type MutatorDefinition,\n type MutatorExecutionFunction,\n type MutatorTypes,\n} from './mutator.ts';\n\n/**\n * Creates a MutatorRegistry from a tree of MutatorDefinitions,\n * optionally extending a base MutatorRegistry.\n *\n * @example\n * ```ts\n * // Create a new registry\n * const mutators = defineMutators({\n * user: {\n * create: defineMutator(...),\n * delete: defineMutator(...),\n * },\n * post: {\n * publish: defineMutator(...),\n * },\n * });\n *\n * // Extend an existing registry (e.g., for server-side overrides)\n * const serverMutators = defineMutators(mutators, {\n * user: {\n * create: defineMutator(...), // overrides mutators.user.create\n * },\n * // post.publish is inherited from mutators\n * });\n *\n * // Access mutators by path\n * const mr = mutators.user.create({name: 'Alice'});\n *\n * // Execute on client\n * zero.mutate(mr);\n *\n * // Execute on server\n * mr.mutator.fn({tx, ctx, args: mr.args});\n *\n * // Lookup by name (for server-side dispatch)\n * const mutator = getMutator(mutators, 'user.create');\n * ```\n */\nexport function defineMutators<\n // let MD infer freely so defaults aren't erased by a MutatorDefinitions constraint\n const MD,\n S extends BaseDefaultSchema = DefaultSchema,\n>(\n // we assert types here for clear error messages\n definitions: MD & AssertMutatorDefinitions<MD>,\n): MutatorRegistry<EnsureMutatorDefinitions<MD>, S>;\n\nexport function defineMutators<\n // same as MD above, but for TBase and TOverrides\n const TBase,\n const TOverrides,\n S extends BaseDefaultSchema = DefaultSchema,\n>(\n base:\n | MutatorRegistry<EnsureMutatorDefinitions<TBase>, S>\n | (TBase & AssertMutatorDefinitions<TBase>),\n overrides: TOverrides & AssertMutatorDefinitions<TOverrides>,\n): MutatorRegistry<\n DeepMerge<\n EnsureMutatorDefinitions<TBase>,\n EnsureMutatorDefinitions<TOverrides>,\n AnyMutatorDefinition\n >,\n S\n>;\n\nexport function defineMutators(\n definitionsOrBase: MutatorDefinitions | AnyMutatorRegistry,\n maybeOverrides?: MutatorDefinitions,\n): AnyMutatorRegistry {\n function processDefinitions(\n definitions: MutatorDefinitions,\n path: string[],\n ): Record<string | symbol, unknown> {\n const result: Record<string | symbol, unknown> = {\n ['~']: 'MutatorRegistry',\n };\n\n for (const [key, value] of Object.entries(definitions)) {\n path.push(key);\n const name = path.join('.');\n\n if (isMutatorDefinition(value)) {\n result[key] = createMutator(name, value);\n } else {\n // Nested definitions\n result[key] = processDefinitions(value, path);\n }\n path.pop();\n }\n\n return result;\n }\n\n if (maybeOverrides !== undefined) {\n // Merge base and overrides\n let base: Record<string | symbol, unknown>;\n if (!isMutatorRegistry(definitionsOrBase)) {\n base = processDefinitions(definitionsOrBase, []);\n } else {\n base = definitionsOrBase;\n }\n\n const processed = processDefinitions(maybeOverrides, []);\n\n const merged = deepMerge(base, processed, isMutatorLeaf);\n merged['~'] = 'MutatorRegistry';\n return merged as AnyMutatorRegistry;\n }\n\n return processDefinitions(\n definitionsOrBase as MutatorDefinitions,\n [],\n ) as AnyMutatorRegistry;\n}\n\nconst isMutatorLeaf = (value: unknown): boolean =>\n !isPlainObject(value) || isMutator(value);\n\n/**\n * Creates a function that can be used to define mutators with a specific schema.\n */\nexport function defineMutatorsWithType<\n TSchema extends Schema,\n>(): TypedDefineMutators<TSchema> {\n return defineMutators;\n}\n\n/**\n * The return type of defineMutatorsWithType. A function matching the\n * defineMutators overloads but with Schema pre-bound.\n */\ntype TypedDefineMutators<S extends Schema> = {\n // Single definitions\n <MD>(\n definitions: MD & AssertMutatorDefinitions<MD>,\n ): MutatorRegistry<EnsureMutatorDefinitions<MD>, S>;\n\n // Base and overrides\n <TBase, TOverrides>(\n base:\n | MutatorRegistry<EnsureMutatorDefinitions<TBase>, S>\n | (TBase & AssertMutatorDefinitions<TBase>),\n overrides: TOverrides,\n ): MutatorRegistry<\n DeepMerge<\n EnsureMutatorDefinitions<TBase>,\n EnsureMutatorDefinitions<TOverrides>,\n AnyMutatorDefinition\n >,\n S\n >;\n};\n\nexport type AssertMutatorDefinitions<MD> = MD extends MutatorDefinitions\n ? unknown\n : never;\n\nexport type EnsureMutatorDefinitions<MD> = MD extends MutatorDefinitions\n ? MD\n : never;\n\n/**\n * Checks if a value is a MutatorRegistry.\n */\nexport function isMutatorRegistry(value: unknown): value is AnyMutatorRegistry {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as Record<string, unknown>)['~'] === 'MutatorRegistry'\n );\n}\n\nexport type MutatorRegistryTypes<TSchema extends Schema> = 'MutatorRegistry' & {\n readonly $schema: TSchema;\n};\n\n/**\n * The result of defineMutators(). A tree of Mutators with a tag for detection.\n */\nexport type MutatorRegistry<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n> = ToMutatorTree<MD, TSchema> & {\n ['~']: MutatorRegistryTypes<TSchema>;\n};\n\n/**\n * A branded type for use in type constraints. Use this instead of\n * `MutatorRegistry<S, C, any>` to avoid TypeScript drilling into\n * the complex ToMutatorTree structure and hitting variance issues.\n */\nexport type AnyMutatorRegistry = {\n ['~']: MutatorRegistryTypes<Schema>;\n [key: string]: unknown;\n};\n\n/**\n * Transforms a MutatorDefinitions into a tree of Mutators.\n * Each MutatorDefinition becomes a Mutator at the same path.\n * Uses TInput for the callable args (TOutput is only used internally for validation).\n */\nexport type ToMutatorTree<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n> = {\n readonly [K in keyof MD]: MD[K] extends AnyMutatorDefinition\n ? // pull types from the phantom property\n Mutator<\n MD[K]['~']['$input'],\n TSchema,\n MD[K]['~']['$context'],\n MD[K]['~']['$wrappedTransaction']\n >\n : MD[K] extends MutatorDefinitions\n ? ToMutatorTree<MD[K], TSchema>\n : never;\n};\n\nexport type FromMutatorTree<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n> = {\n readonly [K in keyof MD]: MD[K] extends AnyMutatorDefinition\n ? // pull types from the phantom property\n Mutator<\n ReadonlyJSONValue | undefined, // intentionally left as generic to avoid variance issues\n TSchema,\n MD[K]['~']['$context'],\n MD[K]['~']['$wrappedTransaction']\n >\n : MD[K] extends MutatorDefinitions\n ? FromMutatorTree<MD[K], TSchema>\n : never;\n}[keyof MD];\n\n/**\n * A tree of MutatorDefinitions, possibly nested.\n */\nexport type MutatorDefinitions = {\n readonly [key: string]: AnyMutatorDefinition | MutatorDefinitions;\n};\n\nfunction createMutator<\n ArgsInput extends ReadonlyJSONValue | undefined,\n ArgsOutput extends ReadonlyJSONValue | undefined,\n TSchema extends Schema,\n C,\n TWrappedTransaction,\n>(\n name: string,\n definition: MutatorDefinition<ArgsInput, ArgsOutput, C, TWrappedTransaction>,\n): Mutator<ArgsInput, TSchema, C, TWrappedTransaction> {\n const {validator} = definition;\n\n // fn takes ReadonlyJSONValue args because it's called during rebase (from\n // stored JSON) and on the server (from wire format). Validation happens here.\n const fn: MutatorExecutionFunction<\n ArgsInput,\n C,\n Transaction<TSchema, TWrappedTransaction>\n > = async options => {\n const validatedArgs = validator\n ? validateInput(name, options.args, validator, 'mutator')\n : (options.args as unknown as ArgsOutput);\n await definition.fn({\n args: validatedArgs,\n ctx: options.ctx as C,\n tx: options.tx,\n });\n };\n\n const mutator = (\n args: ArgsInput,\n ): MutateRequest<ArgsInput, TSchema, C, TWrappedTransaction> => ({\n args,\n '~': 'MutateRequest' as MutateRequestTypes<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >,\n 'mutator': mutator as unknown as Mutator<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >,\n });\n\n mutator.mutatorName = name;\n mutator.fn = fn;\n mutator['~'] = 'Mutator' as unknown as MutatorTypes<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >;\n\n return mutator as unknown as Mutator<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >;\n}\n\nexport function iterateMutators(\n registry: AnyMutatorRegistry,\n): Iterable<AnyMutator> {\n return iterateLeaves(registry, isMutator);\n}\n\n/**\n * Gets a Mutator by its dot-separated name from a MutatorRegistry.\n * Returns undefined if not found.\n */\nexport function getMutator<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n>(\n registry: MutatorRegistry<MD, TSchema>,\n name: string,\n): FromMutatorTree<MD, TSchema> | undefined {\n const m = getValueAtPath(registry, name, '.');\n return m as FromMutatorTree<MD, TSchema> | undefined;\n}\n\n/**\n * Gets a Mutator by its dot-separated name from a MutatorRegistry.\n * Throws if not found.\n */\nexport function mustGetMutator<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n>(\n registry: MutatorRegistry<MD, TSchema>,\n name: string,\n): FromMutatorTree<MD, TSchema> {\n const mutator = getMutator(registry, name);\n if (mutator === undefined) {\n throw new Error(`Mutator not found: ${name}`);\n }\n return mutator;\n}\n"],"mappings":";;;;;AAgGA,SAAgB,eACd,mBACA,gBACoB;CACpB,SAAS,mBACP,aACA,MACkC;EAClC,MAAM,SAA2C,GAC9C,MAAM,kBACT;EAEA,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,WAAW,GAAG;GACtD,KAAK,KAAK,GAAG;GACb,MAAM,OAAO,KAAK,KAAK,GAAG;GAE1B,IAAI,oBAAoB,KAAK,GAC3B,OAAO,OAAO,cAAc,MAAM,KAAK;QAGvC,OAAO,OAAO,mBAAmB,OAAO,IAAI;GAE9C,KAAK,IAAI;EACX;EAEA,OAAO;CACT;CAEA,IAAI,mBAAmB,KAAA,GAAW;EAEhC,IAAI;EACJ,IAAI,CAAC,kBAAkB,iBAAiB,GACtC,OAAO,mBAAmB,mBAAmB,CAAC,CAAC;OAE/C,OAAO;EAGT,MAAM,YAAY,mBAAmB,gBAAgB,CAAC,CAAC;EAEvD,MAAM,SAAS,UAAU,MAAM,WAAW,aAAa;EACvD,OAAO,OAAO;EACd,OAAO;CACT;CAEA,OAAO,mBACL,mBACA,CAAC,CACH;AACF;AAEA,IAAM,iBAAiB,UACrB,CAAC,cAAc,KAAK,KAAK,UAAU,KAAK;;;;AAK1C,SAAgB,yBAEkB;CAChC,OAAO;AACT;;;;AAuCA,SAAgB,kBAAkB,OAA6C;CAC7E,OACE,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,SAAS;AAEhD;AAwEA,SAAS,cAOP,MACA,YACqD;CACrD,MAAM,EAAC,cAAa;CAIpB,MAAM,KAIF,OAAM,YAAW;EACnB,MAAM,gBAAgB,YAClB,cAAc,MAAM,QAAQ,MAAM,WAAW,SAAS,IACrD,QAAQ;EACb,MAAM,WAAW,GAAG;GAClB,MAAM;GACN,KAAK,QAAQ;GACb,IAAI,QAAQ;EACd,CAAC;CACH;CAEA,MAAM,WACJ,UAC+D;EAC/D;EACA,KAAK;EAML,WAAW;CAMb;CAEA,QAAQ,cAAc;CACtB,QAAQ,KAAK;CACb,QAAQ,OAAO;CAOf,OAAO;AAMT;AAEA,SAAgB,gBACd,UACsB;CACtB,OAAO,cAAc,UAAU,SAAS;AAC1C;;;;;AAMA,SAAgB,WAId,UACA,MAC0C;CAE1C,OADU,eAAe,UAAU,MAAM,GAClC;AACT;;;;;AAMA,SAAgB,eAId,UACA,MAC8B;CAC9B,MAAM,UAAU,WAAW,UAAU,IAAI;CACzC,IAAI,YAAY,KAAA,GACd,MAAM,IAAI,MAAM,sBAAsB,MAAM;CAE9C,OAAO;AACT"}
@@ -47,6 +47,7 @@ export declare abstract class QueryDelegateBase implements QueryDelegate {
47
47
  preload<TTable extends keyof TSchema['tables'] & string, TSchema extends Schema, TReturn>(query: Query<TTable, TSchema, TReturn>, options?: PreloadOptions): {
48
48
  cleanup: () => void;
49
49
  complete: Promise<void>;
50
+ cached: Promise<void>;
50
51
  };
51
52
  /**
52
53
  * Default no-op implementation for decorateSourceInput.
@@ -121,6 +122,7 @@ export declare function runImpl<TTable extends keyof TSchema['tables'] & string,
121
122
  export declare function preloadImpl<TTable extends keyof TSchema['tables'] & string, TSchema extends Schema, TReturn>(query: Query<TTable, TSchema, TReturn>, delegate: QueryDelegate, options?: PreloadOptions): {
122
123
  cleanup: () => void;
123
124
  complete: Promise<void>;
125
+ cached: Promise<void>;
124
126
  };
125
127
  export declare function materializeImpl<TTable extends keyof TSchema['tables'] & string, TSchema extends Schema, TReturn, T>(query: Query<TTable, TSchema, TReturn>, delegate: QueryDelegate, factory?: ViewFactory<TTable, TSchema, TReturn, T>, options?: MaterializeOptions): T;
126
128
  //# sourceMappingURL=query-delegate-base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query-delegate-base.d.ts","sourceRoot":"","sources":["../../../../../zql/src/query/query-delegate-base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query-delegate-base.d.ts","sourceRoot":"","sources":["../../../../../zql/src/query/query-delegate-base.ts"],"names":[],"mappings":"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"}
@@ -130,17 +130,20 @@ var QueryDelegateBase = class {
130
130
  async function runImpl(query, delegate, options) {
131
131
  delegate.assertValidRunOptions(options);
132
132
  const v = materializeImpl(query, delegate, void 0, { ttl: options?.ttl });
133
- if (options?.type === "complete") return new Promise((resolve) => {
134
- v.addListener((data, type) => {
135
- if (type === "complete") {
136
- v.destroy();
137
- resolve(data);
138
- } else if (type === "error") {
139
- v.destroy();
140
- resolve(Promise.reject(data));
141
- }
133
+ if (options?.type === "complete" || options?.type === "cached") {
134
+ const acceptCached = options.type === "cached";
135
+ return new Promise((resolve) => {
136
+ v.addListener((data, type) => {
137
+ if (type === "complete" || acceptCached && type === "cached") {
138
+ v.destroy();
139
+ resolve(data);
140
+ } else if (type === "error") {
141
+ v.destroy();
142
+ resolve(Promise.reject(data));
143
+ }
144
+ });
142
145
  });
143
- });
146
+ }
144
147
  options?.type;
145
148
  const ret = v.data;
146
149
  v.destroy();
@@ -149,19 +152,33 @@ async function runImpl(query, delegate, options) {
149
152
  function preloadImpl(query, delegate, options) {
150
153
  const qi = asQueryInternals(query);
151
154
  const ttl = options?.ttl ?? 0;
152
- const { resolve, promise: complete } = resolver();
155
+ const completeResolver = resolver();
156
+ const cachedResolver = resolver();
157
+ const { promise: complete } = completeResolver;
158
+ const { promise: cached } = cachedResolver;
159
+ complete.catch(() => {});
160
+ cached.catch(() => {});
153
161
  const { customQueryID, ast } = qi;
154
- if (customQueryID) return {
155
- cleanup: delegate.addCustomQuery(ast, customQueryID, ttl, (got) => {
156
- if (got) resolve();
157
- }),
158
- complete
162
+ const gotCallback = (got, error) => {
163
+ if (error) {
164
+ cachedResolver.reject(error);
165
+ completeResolver.reject(error);
166
+ return;
167
+ }
168
+ if (got === true) {
169
+ cachedResolver.resolve();
170
+ completeResolver.resolve();
171
+ } else if (got === "cached") cachedResolver.resolve();
159
172
  };
173
+ const cleanup = customQueryID ? delegate.addCustomQuery(ast, customQueryID, ttl, gotCallback) : delegate.addServerQuery(ast, ttl, gotCallback);
174
+ if (delegate.defaultQueryComplete) {
175
+ cachedResolver.resolve();
176
+ completeResolver.resolve();
177
+ }
160
178
  return {
161
- cleanup: delegate.addServerQuery(ast, ttl, (got) => {
162
- if (got) resolve();
163
- }),
164
- complete
179
+ cleanup,
180
+ complete,
181
+ cached
165
182
  };
166
183
  }
167
184
  function materializeImpl(query, delegate, factory = arrayViewFactory, options) {
@@ -172,30 +189,37 @@ function materializeImpl(query, delegate, factory = arrayViewFactory, options) {
172
189
  const queryCompleteResolver = resolver();
173
190
  const deferPipeline = !delegate.pipelinesReady;
174
191
  let attached = !deferPipeline;
175
- let gotQueries = delegate.defaultQueryComplete;
176
- let queryComplete = attached && gotQueries;
192
+ let got = delegate.defaultQueryComplete;
193
+ let queryComplete = attached && got === true;
177
194
  const updateTTL = customQueryID ? (newTTL) => delegate.updateCustomQuery(customQueryID, newTTL) : (newTTL) => delegate.updateServerQuery(ast, newTTL);
178
195
  const maybeResolveComplete = () => {
179
- if (attached && gotQueries && queryComplete !== true) {
196
+ if (attached && got === true && queryComplete !== true) {
180
197
  delegate.addMetric("query-materialization-end-to-end", performance.now() - t0, queryID, ast);
181
198
  queryComplete = true;
182
199
  queryCompleteResolver.resolve(true);
183
200
  }
184
201
  };
185
- const gotCallback = (got, error) => {
202
+ let viewForCached;
203
+ const maybeMarkCached = () => {
204
+ if (attached && got === "cached" && queryComplete === false) viewForCached?.markCached?.();
205
+ };
206
+ let destroyed = false;
207
+ const gotCallback = (value, error) => {
208
+ if (destroyed) return;
186
209
  if (error) {
187
210
  queryCompleteResolver.reject(error);
188
211
  queryComplete = error;
189
212
  return;
190
213
  }
191
- if (got) {
192
- gotQueries = true;
193
- maybeResolveComplete();
194
- }
214
+ got = value;
215
+ if (got === "cached") maybeMarkCached();
216
+ else if (got === false) viewForCached?.unmarkCached?.();
217
+ else maybeResolveComplete();
195
218
  };
196
219
  let removeCommitObserver;
197
220
  let removePendingAttach;
198
221
  const onDestroy = () => {
222
+ destroyed = true;
199
223
  removePendingAttach?.();
200
224
  removePendingAttach = void 0;
201
225
  input.destroy();
@@ -230,7 +254,10 @@ function materializeImpl(query, delegate, factory = arrayViewFactory, options) {
230
254
  attached = true;
231
255
  delegate.addMetric("query-materialization-client", performance.now() - t1, queryID);
232
256
  maybeResolveComplete();
257
+ maybeMarkCached();
233
258
  });
259
+ viewForCached = view;
260
+ maybeMarkCached();
234
261
  return view;
235
262
  }
236
263
  /**