@rocicorp/zero 1.2.0-canary.0 → 1.2.0-canary.10

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 (163) hide show
  1. package/out/ast-to-zql/src/format.d.ts.map +1 -1
  2. package/out/ast-to-zql/src/format.js +6 -6
  3. package/out/ast-to-zql/src/format.js.map +1 -1
  4. package/out/shared/src/bigint-json.d.ts.map +1 -1
  5. package/out/shared/src/bigint-json.js.map +1 -1
  6. package/out/shared/src/btree-set.d.ts.map +1 -1
  7. package/out/shared/src/btree-set.js +73 -41
  8. package/out/shared/src/btree-set.js.map +1 -1
  9. package/out/z2s/src/sql.d.ts +2 -2
  10. package/out/z2s/src/sql.d.ts.map +1 -1
  11. package/out/z2s/src/sql.js +2 -3
  12. package/out/z2s/src/sql.js.map +1 -1
  13. package/out/zero/package.js +6 -6
  14. package/out/zero/package.js.map +1 -1
  15. package/out/zero-cache/src/auth/load-permissions.d.ts +2 -2
  16. package/out/zero-cache/src/auth/load-permissions.d.ts.map +1 -1
  17. package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
  18. package/out/zero-cache/src/config/zero-config.d.ts +9 -1
  19. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  20. package/out/zero-cache/src/config/zero-config.js +21 -3
  21. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  22. package/out/zero-cache/src/custom/fetch.d.ts +1 -1
  23. package/out/zero-cache/src/custom/fetch.d.ts.map +1 -1
  24. package/out/zero-cache/src/custom-queries/transform-query.d.ts.map +1 -1
  25. package/out/zero-cache/src/custom-queries/transform-query.js +4 -1
  26. package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
  27. package/out/zero-cache/src/db/run-transaction.d.ts.map +1 -1
  28. package/out/zero-cache/src/db/run-transaction.js +2 -2
  29. package/out/zero-cache/src/db/run-transaction.js.map +1 -1
  30. package/out/zero-cache/src/db/transaction-pool.d.ts.map +1 -1
  31. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  32. package/out/zero-cache/src/observability/metrics.d.ts +1 -1
  33. package/out/zero-cache/src/observability/metrics.d.ts.map +1 -1
  34. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  35. package/out/zero-cache/src/server/anonymous-otel-start.d.ts.map +1 -1
  36. package/out/zero-cache/src/server/anonymous-otel-start.js +6 -1
  37. package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
  38. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  39. package/out/zero-cache/src/server/change-streamer.js +3 -1
  40. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  41. package/out/zero-cache/src/server/logging.d.ts.map +1 -1
  42. package/out/zero-cache/src/server/logging.js +9 -1
  43. package/out/zero-cache/src/server/logging.js.map +1 -1
  44. package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
  45. package/out/zero-cache/src/server/replicator.js +28 -1
  46. package/out/zero-cache/src/server/replicator.js.map +1 -1
  47. package/out/zero-cache/src/services/change-source/change-source.d.ts +1 -1
  48. package/out/zero-cache/src/services/change-source/change-source.d.ts.map +1 -1
  49. package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts.map +1 -1
  50. package/out/zero-cache/src/services/change-source/common/replica-schema.js +13 -1
  51. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  52. package/out/zero-cache/src/services/change-source/custom/change-source.js +4 -4
  53. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  54. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  55. package/out/zero-cache/src/services/change-source/pg/change-source.js +65 -22
  56. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  57. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +1 -1
  58. package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts +1 -1
  59. package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +1 -1
  60. package/out/zero-cache/src/services/change-streamer/backup-monitor.js +31 -1
  61. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  62. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +4 -4
  63. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  64. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +2 -3
  65. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  66. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +4 -0
  67. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
  68. package/out/zero-cache/src/services/change-streamer/change-streamer.js +9 -1
  69. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  70. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  71. package/out/zero-cache/src/services/change-streamer/storer.js +1 -1
  72. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  73. package/out/zero-cache/src/services/life-cycle.d.ts +1 -0
  74. package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
  75. package/out/zero-cache/src/services/life-cycle.js +2 -2
  76. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  77. package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
  78. package/out/zero-cache/src/services/litestream/commands.js +5 -5
  79. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  80. package/out/zero-cache/src/services/mutagen/pusher.d.ts +2 -2
  81. package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
  82. package/out/zero-cache/src/services/mutagen/pusher.js +7 -4
  83. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  84. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
  85. package/out/zero-cache/src/services/replicator/incremental-sync.js +6 -3
  86. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  87. package/out/zero-cache/src/services/replicator/schema/column-metadata.d.ts +1 -1
  88. package/out/zero-cache/src/services/replicator/schema/column-metadata.d.ts.map +1 -1
  89. package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
  90. package/out/zero-cache/src/services/replicator/schema/replication-state.d.ts.map +1 -1
  91. package/out/zero-cache/src/services/replicator/schema/replication-state.js +6 -3
  92. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  93. package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
  94. package/out/zero-cache/src/services/view-syncer/cvr.js +8 -6
  95. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  96. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +1 -1
  97. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  98. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  99. package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts.map +1 -1
  100. package/out/zero-cache/src/services/view-syncer/row-record-cache.js +13 -7
  101. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  102. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +1 -1
  103. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  104. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  105. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  106. package/out/zero-cache/src/services/view-syncer/view-syncer.js +32 -13
  107. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  108. package/out/zero-cache/src/types/pg.d.ts +1 -0
  109. package/out/zero-cache/src/types/pg.d.ts.map +1 -1
  110. package/out/zero-cache/src/types/pg.js +20 -9
  111. package/out/zero-cache/src/types/pg.js.map +1 -1
  112. package/out/zero-cache/src/workers/connection.js +2 -2
  113. package/out/zero-cache/src/workers/connection.js.map +1 -1
  114. package/out/zero-cache/src/workers/replicator.d.ts +5 -2
  115. package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
  116. package/out/zero-cache/src/workers/replicator.js +10 -6
  117. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  118. package/out/zero-client/src/client/version.js +1 -1
  119. package/out/zero-client/src/client/zero-poke-handler.d.ts.map +1 -1
  120. package/out/zero-client/src/client/zero-poke-handler.js +6 -2
  121. package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
  122. package/out/zero-protocol/src/application-error.d.ts +1 -1
  123. package/out/zero-protocol/src/application-error.d.ts.map +1 -1
  124. package/out/zero-protocol/src/application-error.js.map +1 -1
  125. package/out/zero-types/src/name-mapper.d.ts +1 -0
  126. package/out/zero-types/src/name-mapper.d.ts.map +1 -1
  127. package/out/zero-types/src/name-mapper.js +3 -0
  128. package/out/zero-types/src/name-mapper.js.map +1 -1
  129. package/out/zql/src/builder/builder.d.ts.map +1 -1
  130. package/out/zql/src/builder/builder.js +5 -15
  131. package/out/zql/src/builder/builder.js.map +1 -1
  132. package/out/zql/src/ivm/memory-source.d.ts +1 -1
  133. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  134. package/out/zql/src/ivm/memory-source.js +2 -2
  135. package/out/zql/src/ivm/memory-source.js.map +1 -1
  136. package/out/zql/src/ivm/take.d.ts.map +1 -1
  137. package/out/zql/src/ivm/take.js +2 -2
  138. package/out/zql/src/ivm/take.js.map +1 -1
  139. package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
  140. package/out/zql/src/ivm/view-apply-change.js +34 -26
  141. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  142. package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
  143. package/out/zql/src/planner/planner-debug.js.map +1 -1
  144. package/out/zql/src/query/expression.d.ts +1 -1
  145. package/out/zql/src/query/expression.d.ts.map +1 -1
  146. package/out/zql/src/query/expression.js.map +1 -1
  147. package/out/zql/src/query/query.d.ts +1 -2
  148. package/out/zql/src/query/query.d.ts.map +1 -1
  149. package/out/zqlite/src/db.d.ts.map +1 -1
  150. package/out/zqlite/src/db.js +1 -1
  151. package/out/zqlite/src/db.js.map +1 -1
  152. package/out/zqlite/src/internal/sql.d.ts +2 -2
  153. package/out/zqlite/src/internal/sql.d.ts.map +1 -1
  154. package/out/zqlite/src/internal/sql.js +1 -2
  155. package/out/zqlite/src/internal/sql.js.map +1 -1
  156. package/out/zqlite/src/table-source.d.ts.map +1 -1
  157. package/out/zqlite/src/table-source.js +7 -11
  158. package/out/zqlite/src/table-source.js.map +1 -1
  159. package/package.json +6 -6
  160. package/out/zql/src/ivm/cap.d.ts +0 -32
  161. package/out/zql/src/ivm/cap.d.ts.map +0 -1
  162. package/out/zql/src/ivm/cap.js +0 -226
  163. package/out/zql/src/ivm/cap.js.map +0 -1
@@ -1,226 +0,0 @@
1
- import { assert } from "../../../shared/src/asserts.js";
2
- import { throwOutput } from "./operator.js";
3
- import { constraintMatchesPartitionKey, makePartitionKeyComparator } from "./take.js";
4
- //#region ../zql/src/ivm/cap.ts
5
- /**
6
- * The Cap operator is a count-based limiter for EXISTS subqueries that
7
- * does not require ordering. Unlike Take, it tracks membership by primary
8
- * key set rather than by a sorted bound. This means:
9
- *
10
- * - No comparator needed (no ordering requirement)
11
- * - No `start` or `reverse` fetch support
12
- * - No `#rowHiddenFromFetch` complexity (we can defer when adding to the pk set)
13
- *
14
- * Cap is used in EXISTS child pipelines where only the count of matching
15
- * rows matters, not their order. This allows SQLite to skip ORDER BY
16
- * entirely, enabling much faster query plans.
17
- *
18
- * Cap can count rows globally or by unique value of some partition key
19
- * (same as Take).
20
- */
21
- var Cap = class {
22
- #input;
23
- #storage;
24
- #limit;
25
- #partitionKey;
26
- #partitionKeyComparator;
27
- #primaryKey;
28
- #output = throwOutput;
29
- constructor(input, storage, limit, partitionKey) {
30
- assert(limit >= 0, "Limit must be non-negative");
31
- input.setOutput(this);
32
- this.#input = input;
33
- this.#storage = storage;
34
- this.#limit = limit;
35
- this.#partitionKey = partitionKey;
36
- this.#partitionKeyComparator = partitionKey && makePartitionKeyComparator(partitionKey);
37
- this.#primaryKey = input.getSchema().primaryKey;
38
- }
39
- setOutput(output) {
40
- this.#output = output;
41
- }
42
- getSchema() {
43
- return this.#input.getSchema();
44
- }
45
- *fetch(req) {
46
- assert(!req.start, "Cap does not support start");
47
- assert(!req.reverse, "Cap does not support reverse");
48
- if (!this.#partitionKey || req.constraint && constraintMatchesPartitionKey(req.constraint, this.#partitionKey)) {
49
- const capStateKey = getCapStateKey(this.#partitionKey, req.constraint);
50
- const capState = this.#storage.get(capStateKey);
51
- if (!capState) {
52
- yield* this.#initialFetch(req);
53
- return;
54
- }
55
- if (capState.size === 0) return;
56
- for (const pk of capState.pks) {
57
- const constraint = deserializePKToConstraint(pk, this.#primaryKey);
58
- for (const inputNode of this.#input.fetch({ constraint })) {
59
- if (inputNode === "yield") {
60
- yield inputNode;
61
- continue;
62
- }
63
- yield inputNode;
64
- }
65
- }
66
- return;
67
- }
68
- const pkSetCache = /* @__PURE__ */ new Map();
69
- for (const inputNode of this.#input.fetch(req)) {
70
- if (inputNode === "yield") {
71
- yield inputNode;
72
- continue;
73
- }
74
- const capStateKey = getCapStateKey(this.#partitionKey, inputNode.row);
75
- if (!pkSetCache.has(capStateKey)) {
76
- const capState = this.#storage.get(capStateKey);
77
- pkSetCache.set(capStateKey, capState && capState.size > 0 ? new Set(capState.pks) : null);
78
- }
79
- const pkSet = pkSetCache.get(capStateKey);
80
- if (pkSet) {
81
- const pk = serializePK(inputNode.row, this.#primaryKey);
82
- if (pkSet.has(pk)) yield inputNode;
83
- }
84
- }
85
- }
86
- *#initialFetch(req) {
87
- assert(constraintMatchesPartitionKey(req.constraint, this.#partitionKey), "Constraint should match partition key");
88
- if (this.#limit === 0) return;
89
- const capStateKey = getCapStateKey(this.#partitionKey, req.constraint);
90
- assert(this.#storage.get(capStateKey) === void 0, "Cap state should be undefined");
91
- let size = 0;
92
- const pks = [];
93
- let downstreamEarlyReturn = true;
94
- let exceptionThrown = false;
95
- try {
96
- for (const inputNode of this.#input.fetch(req)) {
97
- if (inputNode === "yield") {
98
- yield "yield";
99
- continue;
100
- }
101
- yield inputNode;
102
- pks.push(serializePK(inputNode.row, this.#primaryKey));
103
- size++;
104
- if (size === this.#limit) break;
105
- }
106
- downstreamEarlyReturn = false;
107
- } catch (e) {
108
- exceptionThrown = true;
109
- throw e;
110
- } finally {
111
- if (!exceptionThrown) {
112
- this.#storage.set(capStateKey, {
113
- size,
114
- pks
115
- });
116
- assert(!downstreamEarlyReturn, "Unexpected early return prevented full hydration");
117
- }
118
- }
119
- }
120
- *push(change) {
121
- if (change.type === "edit") {
122
- yield* this.#pushEditChange(change);
123
- return;
124
- }
125
- const capStateKey = getCapStateKey(this.#partitionKey, change.node.row);
126
- const capState = this.#storage.get(capStateKey);
127
- if (!capState) return;
128
- const pk = serializePK(change.node.row, this.#primaryKey);
129
- if (change.type === "add") {
130
- if (capState.size < this.#limit) {
131
- const pks = [...capState.pks, pk];
132
- this.#storage.set(capStateKey, {
133
- size: capState.size + 1,
134
- pks
135
- });
136
- yield* this.#output.push(change, this);
137
- return;
138
- }
139
- return;
140
- } else if (change.type === "remove") {
141
- const pkIndex = capState.pks.indexOf(pk);
142
- if (pkIndex === -1) return;
143
- const pks = [...capState.pks];
144
- pks.splice(pkIndex, 1);
145
- const newSize = capState.size - 1;
146
- const pkSet = new Set(pks);
147
- const constraint = this.#partitionKey ? Object.fromEntries(this.#partitionKey.map((key) => [key, change.node.row[key]])) : void 0;
148
- let replacement;
149
- for (const node of this.#input.fetch({ constraint })) {
150
- if (node === "yield") {
151
- yield node;
152
- continue;
153
- }
154
- const nodePK = serializePK(node.row, this.#primaryKey);
155
- if (!pkSet.has(nodePK)) {
156
- replacement = node;
157
- break;
158
- }
159
- }
160
- if (replacement) {
161
- this.#storage.set(capStateKey, {
162
- size: newSize,
163
- pks
164
- });
165
- yield* this.#output.push(change, this);
166
- const replacementPK = serializePK(replacement.row, this.#primaryKey);
167
- pks.push(replacementPK);
168
- this.#storage.set(capStateKey, {
169
- size: newSize + 1,
170
- pks
171
- });
172
- yield* this.#output.push({
173
- type: "add",
174
- node: replacement
175
- }, this);
176
- } else {
177
- this.#storage.set(capStateKey, {
178
- size: newSize,
179
- pks
180
- });
181
- yield* this.#output.push(change, this);
182
- }
183
- } else if (change.type === "child") {
184
- if (new Set(capState.pks).has(pk)) yield* this.#output.push(change, this);
185
- }
186
- }
187
- *#pushEditChange(change) {
188
- assert(!this.#partitionKeyComparator || this.#partitionKeyComparator(change.oldNode.row, change.node.row) === 0, "Unexpected change of partition key");
189
- const capStateKey = getCapStateKey(this.#partitionKey, change.oldNode.row);
190
- const capState = this.#storage.get(capStateKey);
191
- if (!capState) return;
192
- const oldPK = serializePK(change.oldNode.row, this.#primaryKey);
193
- if (new Set(capState.pks).has(oldPK)) {
194
- const newPK = serializePK(change.node.row, this.#primaryKey);
195
- if (oldPK !== newPK) {
196
- const pks = capState.pks.map((p) => p === oldPK ? newPK : p);
197
- this.#storage.set(capStateKey, {
198
- size: capState.size,
199
- pks
200
- });
201
- }
202
- yield* this.#output.push(change, this);
203
- }
204
- }
205
- destroy() {
206
- this.#input.destroy();
207
- }
208
- };
209
- function getCapStateKey(partitionKey, rowOrConstraint) {
210
- const partitionValues = [];
211
- if (partitionKey && rowOrConstraint) for (const key of partitionKey) partitionValues.push(rowOrConstraint[key]);
212
- return JSON.stringify(["cap", ...partitionValues]);
213
- }
214
- function serializePK(row, primaryKey) {
215
- return JSON.stringify(primaryKey.map((k) => row[k]));
216
- }
217
- function deserializePKToConstraint(pk, primaryKey) {
218
- const values = JSON.parse(pk);
219
- const constraint = {};
220
- for (let i = 0; i < primaryKey.length; i++) constraint[primaryKey[i]] = values[i];
221
- return constraint;
222
- }
223
- //#endregion
224
- export { Cap };
225
-
226
- //# sourceMappingURL=cap.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cap.js","names":["#input","#storage","#limit","#partitionKey","#partitionKeyComparator","#primaryKey","#output","#initialFetch","#pushEditChange"],"sources":["../../../../../zql/src/ivm/cap.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport type {Row, Value} from '../../../zero-protocol/src/data.ts';\nimport type {PrimaryKey} from '../../../zero-protocol/src/primary-key.ts';\nimport {type Change, type EditChange} from './change.ts';\nimport type {Constraint} from './constraint.ts';\nimport type {Comparator, Node} from './data.ts';\nimport {\n throwOutput,\n type FetchRequest,\n type Input,\n type Operator,\n type Output,\n type Storage,\n} from './operator.ts';\nimport type {SourceSchema} from './schema.ts';\nimport {type Stream} from './stream.ts';\nimport {\n constraintMatchesPartitionKey,\n makePartitionKeyComparator,\n type PartitionKey,\n} from './take.ts';\n\ntype CapState = {\n size: number;\n pks: string[];\n};\n\ninterface CapStorage {\n get(key: string): CapState | undefined;\n set(key: string, value: CapState): void;\n del(key: string): void;\n}\n\n/**\n * The Cap operator is a count-based limiter for EXISTS subqueries that\n * does not require ordering. Unlike Take, it tracks membership by primary\n * key set rather than by a sorted bound. This means:\n *\n * - No comparator needed (no ordering requirement)\n * - No `start` or `reverse` fetch support\n * - No `#rowHiddenFromFetch` complexity (we can defer when adding to the pk set)\n *\n * Cap is used in EXISTS child pipelines where only the count of matching\n * rows matters, not their order. This allows SQLite to skip ORDER BY\n * entirely, enabling much faster query plans.\n *\n * Cap can count rows globally or by unique value of some partition key\n * (same as Take).\n */\nexport class Cap implements Operator {\n readonly #input: Input;\n readonly #storage: CapStorage;\n readonly #limit: number;\n readonly #partitionKey: PartitionKey | undefined;\n readonly #partitionKeyComparator: Comparator | undefined;\n readonly #primaryKey: PrimaryKey;\n\n #output: Output = throwOutput;\n\n constructor(\n input: Input,\n storage: Storage,\n limit: number,\n partitionKey?: PartitionKey,\n ) {\n assert(limit >= 0, 'Limit must be non-negative');\n input.setOutput(this);\n this.#input = input;\n this.#storage = storage as CapStorage;\n this.#limit = limit;\n this.#partitionKey = partitionKey;\n this.#partitionKeyComparator =\n partitionKey && makePartitionKeyComparator(partitionKey);\n this.#primaryKey = input.getSchema().primaryKey;\n }\n\n setOutput(output: Output): void {\n this.#output = output;\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n *fetch(req: FetchRequest): Stream<Node | 'yield'> {\n assert(!req.start, 'Cap does not support start');\n assert(!req.reverse, 'Cap does not support reverse');\n\n if (\n !this.#partitionKey ||\n (req.constraint &&\n constraintMatchesPartitionKey(req.constraint, this.#partitionKey))\n ) {\n const capStateKey = getCapStateKey(this.#partitionKey, req.constraint);\n const capState = this.#storage.get(capStateKey);\n if (!capState) {\n yield* this.#initialFetch(req);\n return;\n }\n if (capState.size === 0) {\n return;\n }\n // PK-based point lookups: fetch each tracked row by its PK directly,\n // rather than scanning the partition and filtering.\n for (const pk of capState.pks) {\n const constraint = deserializePKToConstraint(pk, this.#primaryKey);\n for (const inputNode of this.#input.fetch({constraint})) {\n if (inputNode === 'yield') {\n yield inputNode;\n continue;\n }\n yield inputNode;\n }\n }\n return;\n }\n // There is a partition key, but the fetch is not constrained or constrained\n // on a different key. This currently only happens with nested sub-queries.\n const pkSetCache = new Map<string, Set<string> | null>();\n for (const inputNode of this.#input.fetch(req)) {\n if (inputNode === 'yield') {\n yield inputNode;\n continue;\n }\n const capStateKey = getCapStateKey(this.#partitionKey, inputNode.row);\n if (!pkSetCache.has(capStateKey)) {\n const capState = this.#storage.get(capStateKey);\n pkSetCache.set(\n capStateKey,\n capState && capState.size > 0 ? new Set(capState.pks) : null,\n );\n }\n const pkSet = pkSetCache.get(capStateKey);\n if (pkSet) {\n const pk = serializePK(inputNode.row, this.#primaryKey);\n if (pkSet.has(pk)) {\n yield inputNode;\n }\n }\n }\n }\n\n *#initialFetch(req: FetchRequest): Stream<Node | 'yield'> {\n assert(\n constraintMatchesPartitionKey(req.constraint, this.#partitionKey),\n 'Constraint should match partition key',\n );\n\n if (this.#limit === 0) {\n return;\n }\n\n const capStateKey = getCapStateKey(this.#partitionKey, req.constraint);\n assert(\n this.#storage.get(capStateKey) === undefined,\n 'Cap state should be undefined',\n );\n\n let size = 0;\n const pks: string[] = [];\n let downstreamEarlyReturn = true;\n let exceptionThrown = false;\n try {\n for (const inputNode of this.#input.fetch(req)) {\n if (inputNode === 'yield') {\n yield 'yield';\n continue;\n }\n yield inputNode;\n pks.push(serializePK(inputNode.row, this.#primaryKey));\n size++;\n if (size === this.#limit) {\n break;\n }\n }\n downstreamEarlyReturn = false;\n } catch (e) {\n exceptionThrown = true;\n throw e;\n } finally {\n if (!exceptionThrown) {\n this.#storage.set(capStateKey, {size, pks});\n // If it becomes necessary to support downstream early return, this\n // assert should be removed, and replaced with code that consumes\n // the input stream until limit is reached or the input stream is\n // exhausted so that capState is properly hydrated.\n assert(\n !downstreamEarlyReturn,\n 'Unexpected early return prevented full hydration',\n );\n }\n }\n }\n\n *push(change: Change): Stream<'yield'> {\n if (change.type === 'edit') {\n yield* this.#pushEditChange(change);\n return;\n }\n\n const capStateKey = getCapStateKey(this.#partitionKey, change.node.row);\n const capState = this.#storage.get(capStateKey);\n if (!capState) {\n return;\n }\n\n const pk = serializePK(change.node.row, this.#primaryKey);\n\n if (change.type === 'add') {\n if (capState.size < this.#limit) {\n const pks = [...capState.pks, pk];\n this.#storage.set(capStateKey, {size: capState.size + 1, pks});\n yield* this.#output.push(change, this);\n return;\n }\n // Full — drop\n return;\n } else if (change.type === 'remove') {\n const pkIndex = capState.pks.indexOf(pk);\n if (pkIndex === -1) {\n // Not in our set — drop\n return;\n }\n // Remove from set\n const pks = [...capState.pks];\n pks.splice(pkIndex, 1);\n const newSize = capState.size - 1;\n\n // Try to refill: fetch from input with partition constraint,\n // find first row NOT in PK set\n const pkSet = new Set(pks);\n const constraint = this.#partitionKey\n ? (Object.fromEntries(\n this.#partitionKey.map(key => [key, change.node.row[key]] as const),\n ) as Constraint)\n : undefined;\n\n let replacement: Node | undefined;\n for (const node of this.#input.fetch({constraint})) {\n if (node === 'yield') {\n yield node;\n continue;\n }\n const nodePK = serializePK(node.row, this.#primaryKey);\n if (!pkSet.has(nodePK)) {\n replacement = node;\n break;\n }\n }\n\n if (replacement) {\n // Store state WITHOUT replacement during remove forward,\n // matching Take's pattern of hiding in-flight changes from re-fetches.\n this.#storage.set(capStateKey, {size: newSize, pks});\n yield* this.#output.push(change, this);\n // Now add replacement to set and forward the add.\n const replacementPK = serializePK(replacement.row, this.#primaryKey);\n pks.push(replacementPK);\n this.#storage.set(capStateKey, {size: newSize + 1, pks});\n yield* this.#output.push({type: 'add', node: replacement}, this);\n } else {\n this.#storage.set(capStateKey, {size: newSize, pks});\n yield* this.#output.push(change, this);\n }\n } else if (change.type === 'child') {\n const pkSet = new Set(capState.pks);\n if (pkSet.has(pk)) {\n yield* this.#output.push(change, this);\n }\n }\n }\n\n *#pushEditChange(change: EditChange): Stream<'yield'> {\n assert(\n !this.#partitionKeyComparator ||\n this.#partitionKeyComparator(change.oldNode.row, change.node.row) === 0,\n 'Unexpected change of partition key',\n );\n const capStateKey = getCapStateKey(this.#partitionKey, change.oldNode.row);\n const capState = this.#storage.get(capStateKey);\n if (!capState) {\n return;\n }\n\n const oldPK = serializePK(change.oldNode.row, this.#primaryKey);\n const pkSet = new Set(capState.pks);\n if (pkSet.has(oldPK)) {\n // Update the PK in our set if it changed\n const newPK = serializePK(change.node.row, this.#primaryKey);\n if (oldPK !== newPK) {\n const pks = capState.pks.map(p => (p === oldPK ? newPK : p));\n this.#storage.set(capStateKey, {size: capState.size, pks});\n }\n yield* this.#output.push(change, this);\n }\n // If not in our set, drop\n }\n\n destroy(): void {\n this.#input.destroy();\n }\n}\n\nfunction getCapStateKey(\n partitionKey: PartitionKey | undefined,\n rowOrConstraint: Row | Constraint | undefined,\n): string {\n const partitionValues: Value[] = [];\n\n if (partitionKey && rowOrConstraint) {\n for (const key of partitionKey) {\n partitionValues.push(rowOrConstraint[key]);\n }\n }\n\n return JSON.stringify(['cap', ...partitionValues]);\n}\n\nfunction serializePK(row: Row, primaryKey: PrimaryKey): string {\n return JSON.stringify(primaryKey.map(k => row[k]));\n}\n\nfunction deserializePKToConstraint(\n pk: string,\n primaryKey: PrimaryKey,\n): Constraint {\n const values = JSON.parse(pk) as Value[];\n const constraint: Record<string, Value> = {};\n for (let i = 0; i < primaryKey.length; i++) {\n constraint[primaryKey[i]] = values[i];\n }\n return constraint;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAiDA,IAAa,MAAb,MAAqC;CACnC;CACA;CACA;CACA;CACA;CACA;CAEA,UAAkB;CAElB,YACE,OACA,SACA,OACA,cACA;AACA,SAAO,SAAS,GAAG,6BAA6B;AAChD,QAAM,UAAU,KAAK;AACrB,QAAA,QAAc;AACd,QAAA,UAAgB;AAChB,QAAA,QAAc;AACd,QAAA,eAAqB;AACrB,QAAA,yBACE,gBAAgB,2BAA2B,aAAa;AAC1D,QAAA,aAAmB,MAAM,WAAW,CAAC;;CAGvC,UAAU,QAAsB;AAC9B,QAAA,SAAe;;CAGjB,YAA0B;AACxB,SAAO,MAAA,MAAY,WAAW;;CAGhC,CAAC,MAAM,KAA2C;AAChD,SAAO,CAAC,IAAI,OAAO,6BAA6B;AAChD,SAAO,CAAC,IAAI,SAAS,+BAA+B;AAEpD,MACE,CAAC,MAAA,gBACA,IAAI,cACH,8BAA8B,IAAI,YAAY,MAAA,aAAmB,EACnE;GACA,MAAM,cAAc,eAAe,MAAA,cAAoB,IAAI,WAAW;GACtE,MAAM,WAAW,MAAA,QAAc,IAAI,YAAY;AAC/C,OAAI,CAAC,UAAU;AACb,WAAO,MAAA,aAAmB,IAAI;AAC9B;;AAEF,OAAI,SAAS,SAAS,EACpB;AAIF,QAAK,MAAM,MAAM,SAAS,KAAK;IAC7B,MAAM,aAAa,0BAA0B,IAAI,MAAA,WAAiB;AAClE,SAAK,MAAM,aAAa,MAAA,MAAY,MAAM,EAAC,YAAW,CAAC,EAAE;AACvD,SAAI,cAAc,SAAS;AACzB,YAAM;AACN;;AAEF,WAAM;;;AAGV;;EAIF,MAAM,6BAAa,IAAI,KAAiC;AACxD,OAAK,MAAM,aAAa,MAAA,MAAY,MAAM,IAAI,EAAE;AAC9C,OAAI,cAAc,SAAS;AACzB,UAAM;AACN;;GAEF,MAAM,cAAc,eAAe,MAAA,cAAoB,UAAU,IAAI;AACrE,OAAI,CAAC,WAAW,IAAI,YAAY,EAAE;IAChC,MAAM,WAAW,MAAA,QAAc,IAAI,YAAY;AAC/C,eAAW,IACT,aACA,YAAY,SAAS,OAAO,IAAI,IAAI,IAAI,SAAS,IAAI,GAAG,KACzD;;GAEH,MAAM,QAAQ,WAAW,IAAI,YAAY;AACzC,OAAI,OAAO;IACT,MAAM,KAAK,YAAY,UAAU,KAAK,MAAA,WAAiB;AACvD,QAAI,MAAM,IAAI,GAAG,CACf,OAAM;;;;CAMd,EAAA,aAAe,KAA2C;AACxD,SACE,8BAA8B,IAAI,YAAY,MAAA,aAAmB,EACjE,wCACD;AAED,MAAI,MAAA,UAAgB,EAClB;EAGF,MAAM,cAAc,eAAe,MAAA,cAAoB,IAAI,WAAW;AACtE,SACE,MAAA,QAAc,IAAI,YAAY,KAAK,KAAA,GACnC,gCACD;EAED,IAAI,OAAO;EACX,MAAM,MAAgB,EAAE;EACxB,IAAI,wBAAwB;EAC5B,IAAI,kBAAkB;AACtB,MAAI;AACF,QAAK,MAAM,aAAa,MAAA,MAAY,MAAM,IAAI,EAAE;AAC9C,QAAI,cAAc,SAAS;AACzB,WAAM;AACN;;AAEF,UAAM;AACN,QAAI,KAAK,YAAY,UAAU,KAAK,MAAA,WAAiB,CAAC;AACtD;AACA,QAAI,SAAS,MAAA,MACX;;AAGJ,2BAAwB;WACjB,GAAG;AACV,qBAAkB;AAClB,SAAM;YACE;AACR,OAAI,CAAC,iBAAiB;AACpB,UAAA,QAAc,IAAI,aAAa;KAAC;KAAM;KAAI,CAAC;AAK3C,WACE,CAAC,uBACD,mDACD;;;;CAKP,CAAC,KAAK,QAAiC;AACrC,MAAI,OAAO,SAAS,QAAQ;AAC1B,UAAO,MAAA,eAAqB,OAAO;AACnC;;EAGF,MAAM,cAAc,eAAe,MAAA,cAAoB,OAAO,KAAK,IAAI;EACvE,MAAM,WAAW,MAAA,QAAc,IAAI,YAAY;AAC/C,MAAI,CAAC,SACH;EAGF,MAAM,KAAK,YAAY,OAAO,KAAK,KAAK,MAAA,WAAiB;AAEzD,MAAI,OAAO,SAAS,OAAO;AACzB,OAAI,SAAS,OAAO,MAAA,OAAa;IAC/B,MAAM,MAAM,CAAC,GAAG,SAAS,KAAK,GAAG;AACjC,UAAA,QAAc,IAAI,aAAa;KAAC,MAAM,SAAS,OAAO;KAAG;KAAI,CAAC;AAC9D,WAAO,MAAA,OAAa,KAAK,QAAQ,KAAK;AACtC;;AAGF;aACS,OAAO,SAAS,UAAU;GACnC,MAAM,UAAU,SAAS,IAAI,QAAQ,GAAG;AACxC,OAAI,YAAY,GAEd;GAGF,MAAM,MAAM,CAAC,GAAG,SAAS,IAAI;AAC7B,OAAI,OAAO,SAAS,EAAE;GACtB,MAAM,UAAU,SAAS,OAAO;GAIhC,MAAM,QAAQ,IAAI,IAAI,IAAI;GAC1B,MAAM,aAAa,MAAA,eACd,OAAO,YACN,MAAA,aAAmB,KAAI,QAAO,CAAC,KAAK,OAAO,KAAK,IAAI,KAAK,CAAU,CACpE,GACD,KAAA;GAEJ,IAAI;AACJ,QAAK,MAAM,QAAQ,MAAA,MAAY,MAAM,EAAC,YAAW,CAAC,EAAE;AAClD,QAAI,SAAS,SAAS;AACpB,WAAM;AACN;;IAEF,MAAM,SAAS,YAAY,KAAK,KAAK,MAAA,WAAiB;AACtD,QAAI,CAAC,MAAM,IAAI,OAAO,EAAE;AACtB,mBAAc;AACd;;;AAIJ,OAAI,aAAa;AAGf,UAAA,QAAc,IAAI,aAAa;KAAC,MAAM;KAAS;KAAI,CAAC;AACpD,WAAO,MAAA,OAAa,KAAK,QAAQ,KAAK;IAEtC,MAAM,gBAAgB,YAAY,YAAY,KAAK,MAAA,WAAiB;AACpE,QAAI,KAAK,cAAc;AACvB,UAAA,QAAc,IAAI,aAAa;KAAC,MAAM,UAAU;KAAG;KAAI,CAAC;AACxD,WAAO,MAAA,OAAa,KAAK;KAAC,MAAM;KAAO,MAAM;KAAY,EAAE,KAAK;UAC3D;AACL,UAAA,QAAc,IAAI,aAAa;KAAC,MAAM;KAAS;KAAI,CAAC;AACpD,WAAO,MAAA,OAAa,KAAK,QAAQ,KAAK;;aAE/B,OAAO,SAAS;OACX,IAAI,IAAI,SAAS,IAAI,CACzB,IAAI,GAAG,CACf,QAAO,MAAA,OAAa,KAAK,QAAQ,KAAK;;;CAK5C,EAAA,eAAiB,QAAqC;AACpD,SACE,CAAC,MAAA,0BACC,MAAA,uBAA6B,OAAO,QAAQ,KAAK,OAAO,KAAK,IAAI,KAAK,GACxE,qCACD;EACD,MAAM,cAAc,eAAe,MAAA,cAAoB,OAAO,QAAQ,IAAI;EAC1E,MAAM,WAAW,MAAA,QAAc,IAAI,YAAY;AAC/C,MAAI,CAAC,SACH;EAGF,MAAM,QAAQ,YAAY,OAAO,QAAQ,KAAK,MAAA,WAAiB;AAE/D,MADc,IAAI,IAAI,SAAS,IAAI,CACzB,IAAI,MAAM,EAAE;GAEpB,MAAM,QAAQ,YAAY,OAAO,KAAK,KAAK,MAAA,WAAiB;AAC5D,OAAI,UAAU,OAAO;IACnB,MAAM,MAAM,SAAS,IAAI,KAAI,MAAM,MAAM,QAAQ,QAAQ,EAAG;AAC5D,UAAA,QAAc,IAAI,aAAa;KAAC,MAAM,SAAS;KAAM;KAAI,CAAC;;AAE5D,UAAO,MAAA,OAAa,KAAK,QAAQ,KAAK;;;CAK1C,UAAgB;AACd,QAAA,MAAY,SAAS;;;AAIzB,SAAS,eACP,cACA,iBACQ;CACR,MAAM,kBAA2B,EAAE;AAEnC,KAAI,gBAAgB,gBAClB,MAAK,MAAM,OAAO,aAChB,iBAAgB,KAAK,gBAAgB,KAAK;AAI9C,QAAO,KAAK,UAAU,CAAC,OAAO,GAAG,gBAAgB,CAAC;;AAGpD,SAAS,YAAY,KAAU,YAAgC;AAC7D,QAAO,KAAK,UAAU,WAAW,KAAI,MAAK,IAAI,GAAG,CAAC;;AAGpD,SAAS,0BACP,IACA,YACY;CACZ,MAAM,SAAS,KAAK,MAAM,GAAG;CAC7B,MAAM,aAAoC,EAAE;AAC5C,MAAK,IAAI,IAAI,GAAG,IAAI,WAAW,QAAQ,IACrC,YAAW,WAAW,MAAM,OAAO;AAErC,QAAO"}