@rocicorp/zero 1.12.0-canary.1 → 1.12.0-canary.3
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.
- package/out/zero/package.js +1 -1
- package/out/zero/package.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +18 -0
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.js +46 -20
- package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +4 -3
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +5 -2
- package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-protocol/src/inspect-down.d.ts +81 -81
- package/out/zero-protocol/src/poke.d.ts +6 -6
- package/out/zero-protocol/src/up.d.ts +60 -60
- package/out/zql/src/ivm/cap.js +2 -4
- package/out/zql/src/ivm/cap.js.map +1 -1
- package/out/zql/src/ivm/take.js +2 -4
- package/out/zql/src/ivm/take.js.map +1 -1
- package/out/zqlite/src/database-storage.d.ts.map +1 -1
- package/out/zqlite/src/database-storage.js +38 -6
- package/out/zqlite/src/database-storage.js.map +1 -1
- package/out/zqlite/src/fetch-sql.d.ts +27 -0
- package/out/zqlite/src/fetch-sql.d.ts.map +1 -0
- package/out/zqlite/src/fetch-sql.js +112 -0
- package/out/zqlite/src/fetch-sql.js.map +1 -0
- package/out/zqlite/src/query-builder.d.ts +11 -1
- package/out/zqlite/src/query-builder.d.ts.map +1 -1
- package/out/zqlite/src/query-builder.js +22 -7
- package/out/zqlite/src/query-builder.js.map +1 -1
- package/out/zqlite/src/table-source.d.ts +9 -2
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +11 -14
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +1 -1
|
@@ -100,33 +100,6 @@ export declare const inspectAnalyzeQueryDownSchema: v.ObjectType<Omit<{
|
|
|
100
100
|
type: "attempt-start";
|
|
101
101
|
attemptNumber: number;
|
|
102
102
|
totalAttempts: number;
|
|
103
|
-
} | {
|
|
104
|
-
type: "connection-selected";
|
|
105
|
-
attemptNumber: number;
|
|
106
|
-
connection: string;
|
|
107
|
-
cost: number;
|
|
108
|
-
isRoot: boolean;
|
|
109
|
-
} | {
|
|
110
|
-
type: "plan-failed";
|
|
111
|
-
attemptNumber: number;
|
|
112
|
-
reason: string;
|
|
113
|
-
} | {
|
|
114
|
-
type: "best-plan-selected";
|
|
115
|
-
bestAttemptNumber: number;
|
|
116
|
-
totalCost: number;
|
|
117
|
-
flipPattern: number;
|
|
118
|
-
joinStates: {
|
|
119
|
-
join: string;
|
|
120
|
-
type: "flipped" | "semi" | "unflippable" | v.Unrecognized<string>;
|
|
121
|
-
}[];
|
|
122
|
-
} | {
|
|
123
|
-
type: "node-constraint";
|
|
124
|
-
attemptNumber?: number | undefined;
|
|
125
|
-
nodeType: "connection" | "fan-in" | "fan-out" | "filter" | "join" | "terminus" | v.Unrecognized<string>;
|
|
126
|
-
node: string;
|
|
127
|
-
branchPattern: number[];
|
|
128
|
-
constraint?: Record<string, unknown> | null | undefined;
|
|
129
|
-
from: string;
|
|
130
103
|
} | {
|
|
131
104
|
type: "connection-costs";
|
|
132
105
|
attemptNumber: number;
|
|
@@ -152,6 +125,12 @@ export declare const inspectAnalyzeQueryDownSchema: v.ObjectType<Omit<{
|
|
|
152
125
|
limit?: number | undefined;
|
|
153
126
|
}>;
|
|
154
127
|
}[];
|
|
128
|
+
} | {
|
|
129
|
+
type: "connection-selected";
|
|
130
|
+
attemptNumber: number;
|
|
131
|
+
connection: string;
|
|
132
|
+
cost: number;
|
|
133
|
+
isRoot: boolean;
|
|
155
134
|
} | {
|
|
156
135
|
type: "constraints-propagated";
|
|
157
136
|
attemptNumber: number;
|
|
@@ -176,6 +155,19 @@ export declare const inspectAnalyzeQueryDownSchema: v.ObjectType<Omit<{
|
|
|
176
155
|
join: string;
|
|
177
156
|
type: "flipped" | "semi" | "unflippable" | v.Unrecognized<string>;
|
|
178
157
|
}[];
|
|
158
|
+
} | {
|
|
159
|
+
type: "plan-failed";
|
|
160
|
+
attemptNumber: number;
|
|
161
|
+
reason: string;
|
|
162
|
+
} | {
|
|
163
|
+
type: "best-plan-selected";
|
|
164
|
+
bestAttemptNumber: number;
|
|
165
|
+
totalCost: number;
|
|
166
|
+
flipPattern: number;
|
|
167
|
+
joinStates: {
|
|
168
|
+
join: string;
|
|
169
|
+
type: "flipped" | "semi" | "unflippable" | v.Unrecognized<string>;
|
|
170
|
+
}[];
|
|
179
171
|
} | {
|
|
180
172
|
type: "node-cost";
|
|
181
173
|
attemptNumber?: number | undefined;
|
|
@@ -194,6 +186,14 @@ export declare const inspectAnalyzeQueryDownSchema: v.ObjectType<Omit<{
|
|
|
194
186
|
filters?: import("./ast.ts").Condition | undefined;
|
|
195
187
|
ordering?: readonly (readonly [string, "asc" | "desc"])[] | undefined;
|
|
196
188
|
joinType?: "flipped" | "semi" | "unflippable" | v.Unrecognized<string> | undefined;
|
|
189
|
+
} | {
|
|
190
|
+
type: "node-constraint";
|
|
191
|
+
attemptNumber?: number | undefined;
|
|
192
|
+
nodeType: "connection" | "fan-in" | "fan-out" | "filter" | "join" | "terminus" | v.Unrecognized<string>;
|
|
193
|
+
node: string;
|
|
194
|
+
branchPattern: number[];
|
|
195
|
+
constraint?: Record<string, unknown> | null | undefined;
|
|
196
|
+
from: string;
|
|
197
197
|
})[]>;
|
|
198
198
|
}, undefined>;
|
|
199
199
|
}, undefined>;
|
|
@@ -266,33 +266,6 @@ export declare const inspectDownBodySchema: v.UnionType<[v.ObjectType<Omit<{
|
|
|
266
266
|
type: "attempt-start";
|
|
267
267
|
attemptNumber: number;
|
|
268
268
|
totalAttempts: number;
|
|
269
|
-
} | {
|
|
270
|
-
type: "connection-selected";
|
|
271
|
-
attemptNumber: number;
|
|
272
|
-
connection: string;
|
|
273
|
-
cost: number;
|
|
274
|
-
isRoot: boolean;
|
|
275
|
-
} | {
|
|
276
|
-
type: "plan-failed";
|
|
277
|
-
attemptNumber: number;
|
|
278
|
-
reason: string;
|
|
279
|
-
} | {
|
|
280
|
-
type: "best-plan-selected";
|
|
281
|
-
bestAttemptNumber: number;
|
|
282
|
-
totalCost: number;
|
|
283
|
-
flipPattern: number;
|
|
284
|
-
joinStates: {
|
|
285
|
-
join: string;
|
|
286
|
-
type: "flipped" | "semi" | "unflippable" | v.Unrecognized<string>;
|
|
287
|
-
}[];
|
|
288
|
-
} | {
|
|
289
|
-
type: "node-constraint";
|
|
290
|
-
attemptNumber?: number | undefined;
|
|
291
|
-
nodeType: "connection" | "fan-in" | "fan-out" | "filter" | "join" | "terminus" | v.Unrecognized<string>;
|
|
292
|
-
node: string;
|
|
293
|
-
branchPattern: number[];
|
|
294
|
-
constraint?: Record<string, unknown> | null | undefined;
|
|
295
|
-
from: string;
|
|
296
269
|
} | {
|
|
297
270
|
type: "connection-costs";
|
|
298
271
|
attemptNumber: number;
|
|
@@ -318,6 +291,12 @@ export declare const inspectDownBodySchema: v.UnionType<[v.ObjectType<Omit<{
|
|
|
318
291
|
limit?: number | undefined;
|
|
319
292
|
}>;
|
|
320
293
|
}[];
|
|
294
|
+
} | {
|
|
295
|
+
type: "connection-selected";
|
|
296
|
+
attemptNumber: number;
|
|
297
|
+
connection: string;
|
|
298
|
+
cost: number;
|
|
299
|
+
isRoot: boolean;
|
|
321
300
|
} | {
|
|
322
301
|
type: "constraints-propagated";
|
|
323
302
|
attemptNumber: number;
|
|
@@ -342,6 +321,19 @@ export declare const inspectDownBodySchema: v.UnionType<[v.ObjectType<Omit<{
|
|
|
342
321
|
join: string;
|
|
343
322
|
type: "flipped" | "semi" | "unflippable" | v.Unrecognized<string>;
|
|
344
323
|
}[];
|
|
324
|
+
} | {
|
|
325
|
+
type: "plan-failed";
|
|
326
|
+
attemptNumber: number;
|
|
327
|
+
reason: string;
|
|
328
|
+
} | {
|
|
329
|
+
type: "best-plan-selected";
|
|
330
|
+
bestAttemptNumber: number;
|
|
331
|
+
totalCost: number;
|
|
332
|
+
flipPattern: number;
|
|
333
|
+
joinStates: {
|
|
334
|
+
join: string;
|
|
335
|
+
type: "flipped" | "semi" | "unflippable" | v.Unrecognized<string>;
|
|
336
|
+
}[];
|
|
345
337
|
} | {
|
|
346
338
|
type: "node-cost";
|
|
347
339
|
attemptNumber?: number | undefined;
|
|
@@ -360,6 +352,14 @@ export declare const inspectDownBodySchema: v.UnionType<[v.ObjectType<Omit<{
|
|
|
360
352
|
filters?: import("./ast.ts").Condition | undefined;
|
|
361
353
|
ordering?: readonly (readonly [string, "asc" | "desc"])[] | undefined;
|
|
362
354
|
joinType?: "flipped" | "semi" | "unflippable" | v.Unrecognized<string> | undefined;
|
|
355
|
+
} | {
|
|
356
|
+
type: "node-constraint";
|
|
357
|
+
attemptNumber?: number | undefined;
|
|
358
|
+
nodeType: "connection" | "fan-in" | "fan-out" | "filter" | "join" | "terminus" | v.Unrecognized<string>;
|
|
359
|
+
node: string;
|
|
360
|
+
branchPattern: number[];
|
|
361
|
+
constraint?: Record<string, unknown> | null | undefined;
|
|
362
|
+
from: string;
|
|
363
363
|
})[]>;
|
|
364
364
|
}, undefined>;
|
|
365
365
|
}, undefined>, v.ObjectType<Omit<{
|
|
@@ -429,33 +429,6 @@ export declare const inspectDownMessageSchema: v.TupleType<[v.Type<"inspect">, v
|
|
|
429
429
|
type: "attempt-start";
|
|
430
430
|
attemptNumber: number;
|
|
431
431
|
totalAttempts: number;
|
|
432
|
-
} | {
|
|
433
|
-
type: "connection-selected";
|
|
434
|
-
attemptNumber: number;
|
|
435
|
-
connection: string;
|
|
436
|
-
cost: number;
|
|
437
|
-
isRoot: boolean;
|
|
438
|
-
} | {
|
|
439
|
-
type: "plan-failed";
|
|
440
|
-
attemptNumber: number;
|
|
441
|
-
reason: string;
|
|
442
|
-
} | {
|
|
443
|
-
type: "best-plan-selected";
|
|
444
|
-
bestAttemptNumber: number;
|
|
445
|
-
totalCost: number;
|
|
446
|
-
flipPattern: number;
|
|
447
|
-
joinStates: {
|
|
448
|
-
join: string;
|
|
449
|
-
type: "flipped" | "semi" | "unflippable" | v.Unrecognized<string>;
|
|
450
|
-
}[];
|
|
451
|
-
} | {
|
|
452
|
-
type: "node-constraint";
|
|
453
|
-
attemptNumber?: number | undefined;
|
|
454
|
-
nodeType: "connection" | "fan-in" | "fan-out" | "filter" | "join" | "terminus" | v.Unrecognized<string>;
|
|
455
|
-
node: string;
|
|
456
|
-
branchPattern: number[];
|
|
457
|
-
constraint?: Record<string, unknown> | null | undefined;
|
|
458
|
-
from: string;
|
|
459
432
|
} | {
|
|
460
433
|
type: "connection-costs";
|
|
461
434
|
attemptNumber: number;
|
|
@@ -481,6 +454,12 @@ export declare const inspectDownMessageSchema: v.TupleType<[v.Type<"inspect">, v
|
|
|
481
454
|
limit?: number | undefined;
|
|
482
455
|
}>;
|
|
483
456
|
}[];
|
|
457
|
+
} | {
|
|
458
|
+
type: "connection-selected";
|
|
459
|
+
attemptNumber: number;
|
|
460
|
+
connection: string;
|
|
461
|
+
cost: number;
|
|
462
|
+
isRoot: boolean;
|
|
484
463
|
} | {
|
|
485
464
|
type: "constraints-propagated";
|
|
486
465
|
attemptNumber: number;
|
|
@@ -505,6 +484,19 @@ export declare const inspectDownMessageSchema: v.TupleType<[v.Type<"inspect">, v
|
|
|
505
484
|
join: string;
|
|
506
485
|
type: "flipped" | "semi" | "unflippable" | v.Unrecognized<string>;
|
|
507
486
|
}[];
|
|
487
|
+
} | {
|
|
488
|
+
type: "plan-failed";
|
|
489
|
+
attemptNumber: number;
|
|
490
|
+
reason: string;
|
|
491
|
+
} | {
|
|
492
|
+
type: "best-plan-selected";
|
|
493
|
+
bestAttemptNumber: number;
|
|
494
|
+
totalCost: number;
|
|
495
|
+
flipPattern: number;
|
|
496
|
+
joinStates: {
|
|
497
|
+
join: string;
|
|
498
|
+
type: "flipped" | "semi" | "unflippable" | v.Unrecognized<string>;
|
|
499
|
+
}[];
|
|
508
500
|
} | {
|
|
509
501
|
type: "node-cost";
|
|
510
502
|
attemptNumber?: number | undefined;
|
|
@@ -523,6 +515,14 @@ export declare const inspectDownMessageSchema: v.TupleType<[v.Type<"inspect">, v
|
|
|
523
515
|
filters?: import("./ast.ts").Condition | undefined;
|
|
524
516
|
ordering?: readonly (readonly [string, "asc" | "desc"])[] | undefined;
|
|
525
517
|
joinType?: "flipped" | "semi" | "unflippable" | v.Unrecognized<string> | undefined;
|
|
518
|
+
} | {
|
|
519
|
+
type: "node-constraint";
|
|
520
|
+
attemptNumber?: number | undefined;
|
|
521
|
+
nodeType: "connection" | "fan-in" | "fan-out" | "filter" | "join" | "terminus" | v.Unrecognized<string>;
|
|
522
|
+
node: string;
|
|
523
|
+
branchPattern: number[];
|
|
524
|
+
constraint?: Record<string, unknown> | null | undefined;
|
|
525
|
+
from: string;
|
|
526
526
|
})[]>;
|
|
527
527
|
}, undefined>;
|
|
528
528
|
}, undefined>, v.ObjectType<Omit<{
|
|
@@ -85,14 +85,14 @@ export declare const pokePartBodySchema: v.ObjectType<{
|
|
|
85
85
|
clientID: string;
|
|
86
86
|
};
|
|
87
87
|
result: {
|
|
88
|
-
data?: import("../../shared/src/json.ts").ReadonlyJSONValue | undefined;
|
|
89
|
-
} | {
|
|
90
88
|
error: "app";
|
|
91
89
|
message?: string | undefined;
|
|
92
90
|
details?: import("../../shared/src/json.ts").ReadonlyJSONValue | undefined;
|
|
93
91
|
} | {
|
|
94
92
|
error: "alreadyProcessed" | "oooMutation";
|
|
95
93
|
details?: import("../../shared/src/json.ts").ReadonlyJSONValue | undefined;
|
|
94
|
+
} | {
|
|
95
|
+
data?: import("../../shared/src/json.ts").ReadonlyJSONValue | undefined;
|
|
96
96
|
};
|
|
97
97
|
};
|
|
98
98
|
} | {
|
|
@@ -156,14 +156,14 @@ export declare const pokePartsSchema: v.ArrayType<v.ObjectType<{
|
|
|
156
156
|
clientID: string;
|
|
157
157
|
};
|
|
158
158
|
result: {
|
|
159
|
-
data?: import("../../shared/src/json.ts").ReadonlyJSONValue | undefined;
|
|
160
|
-
} | {
|
|
161
159
|
error: "app";
|
|
162
160
|
message?: string | undefined;
|
|
163
161
|
details?: import("../../shared/src/json.ts").ReadonlyJSONValue | undefined;
|
|
164
162
|
} | {
|
|
165
163
|
error: "alreadyProcessed" | "oooMutation";
|
|
166
164
|
details?: import("../../shared/src/json.ts").ReadonlyJSONValue | undefined;
|
|
165
|
+
} | {
|
|
166
|
+
data?: import("../../shared/src/json.ts").ReadonlyJSONValue | undefined;
|
|
167
167
|
};
|
|
168
168
|
};
|
|
169
169
|
} | {
|
|
@@ -240,14 +240,14 @@ export declare const pokePartMessageSchema: v.TupleType<[v.Type<"pokePart">, v.O
|
|
|
240
240
|
clientID: string;
|
|
241
241
|
};
|
|
242
242
|
result: {
|
|
243
|
-
data?: import("../../shared/src/json.ts").ReadonlyJSONValue | undefined;
|
|
244
|
-
} | {
|
|
245
243
|
error: "app";
|
|
246
244
|
message?: string | undefined;
|
|
247
245
|
details?: import("../../shared/src/json.ts").ReadonlyJSONValue | undefined;
|
|
248
246
|
} | {
|
|
249
247
|
error: "alreadyProcessed" | "oooMutation";
|
|
250
248
|
details?: import("../../shared/src/json.ts").ReadonlyJSONValue | undefined;
|
|
249
|
+
} | {
|
|
250
|
+
data?: import("../../shared/src/json.ts").ReadonlyJSONValue | undefined;
|
|
251
251
|
};
|
|
252
252
|
};
|
|
253
253
|
} | {
|
|
@@ -4,17 +4,17 @@ export declare const upstreamSchema: v.Type<v.UnrecognizedTuple | ["ackMutationR
|
|
|
4
4
|
clientID: string;
|
|
5
5
|
}] | ["changeDesiredQueries", {
|
|
6
6
|
desiredQueriesPatch: ({
|
|
7
|
+
op: "del";
|
|
8
|
+
hash: string;
|
|
9
|
+
} | {
|
|
10
|
+
op: "clear";
|
|
11
|
+
} | {
|
|
7
12
|
op: "put";
|
|
8
13
|
hash: string;
|
|
9
14
|
ttl?: number | undefined;
|
|
10
15
|
ast?: import("./ast.ts").AST | undefined;
|
|
11
16
|
name?: string | undefined;
|
|
12
17
|
args?: readonly import("../../shared/src/json.ts").ReadonlyJSONValue[] | undefined;
|
|
13
|
-
} | {
|
|
14
|
-
op: "del";
|
|
15
|
-
hash: string;
|
|
16
|
-
} | {
|
|
17
|
-
op: "clear";
|
|
18
18
|
})[];
|
|
19
19
|
traceparent?: string | undefined;
|
|
20
20
|
}] | ["closeConnection", unknown[]] | ["deleteClients", {
|
|
@@ -22,17 +22,17 @@ export declare const upstreamSchema: v.Type<v.UnrecognizedTuple | ["ackMutationR
|
|
|
22
22
|
readonly clientGroupIDs?: readonly string[] | undefined;
|
|
23
23
|
}] | ["initConnection", {
|
|
24
24
|
desiredQueriesPatch: ({
|
|
25
|
+
op: "del";
|
|
26
|
+
hash: string;
|
|
27
|
+
} | {
|
|
28
|
+
op: "clear";
|
|
29
|
+
} | {
|
|
25
30
|
op: "put";
|
|
26
31
|
hash: string;
|
|
27
32
|
ttl?: number | undefined;
|
|
28
33
|
ast?: import("./ast.ts").AST | undefined;
|
|
29
34
|
name?: string | undefined;
|
|
30
35
|
args?: readonly import("../../shared/src/json.ts").ReadonlyJSONValue[] | undefined;
|
|
31
|
-
} | {
|
|
32
|
-
op: "del";
|
|
33
|
-
hash: string;
|
|
34
|
-
} | {
|
|
35
|
-
op: "clear";
|
|
36
36
|
})[];
|
|
37
37
|
clientSchema?: {
|
|
38
38
|
tables: Record<string, {
|
|
@@ -135,17 +135,17 @@ export declare const upstreamSchema: v.Type<v.UnrecognizedTuple | ["ackMutationR
|
|
|
135
135
|
clientID: string;
|
|
136
136
|
}] | ["changeDesiredQueries", {
|
|
137
137
|
desiredQueriesPatch: ({
|
|
138
|
+
op: "del";
|
|
139
|
+
hash: string;
|
|
140
|
+
} | {
|
|
141
|
+
op: "clear";
|
|
142
|
+
} | {
|
|
138
143
|
op: "put";
|
|
139
144
|
hash: string;
|
|
140
145
|
ttl?: number | undefined;
|
|
141
146
|
ast?: import("./ast.ts").AST | undefined;
|
|
142
147
|
name?: string | undefined;
|
|
143
148
|
args?: readonly import("../../shared/src/json.ts").ReadonlyJSONValue[] | undefined;
|
|
144
|
-
} | {
|
|
145
|
-
op: "del";
|
|
146
|
-
hash: string;
|
|
147
|
-
} | {
|
|
148
|
-
op: "clear";
|
|
149
149
|
})[];
|
|
150
150
|
traceparent?: string | undefined;
|
|
151
151
|
}] | ["closeConnection", unknown[]] | ["deleteClients", {
|
|
@@ -153,17 +153,17 @@ export declare const upstreamSchema: v.Type<v.UnrecognizedTuple | ["ackMutationR
|
|
|
153
153
|
readonly clientGroupIDs?: readonly string[] | undefined;
|
|
154
154
|
}] | ["initConnection", {
|
|
155
155
|
desiredQueriesPatch: ({
|
|
156
|
+
op: "del";
|
|
157
|
+
hash: string;
|
|
158
|
+
} | {
|
|
159
|
+
op: "clear";
|
|
160
|
+
} | {
|
|
156
161
|
op: "put";
|
|
157
162
|
hash: string;
|
|
158
163
|
ttl?: number | undefined;
|
|
159
164
|
ast?: import("./ast.ts").AST | undefined;
|
|
160
165
|
name?: string | undefined;
|
|
161
166
|
args?: readonly import("../../shared/src/json.ts").ReadonlyJSONValue[] | undefined;
|
|
162
|
-
} | {
|
|
163
|
-
op: "del";
|
|
164
|
-
hash: string;
|
|
165
|
-
} | {
|
|
166
|
-
op: "clear";
|
|
167
167
|
})[];
|
|
168
168
|
clientSchema?: {
|
|
169
169
|
tables: Record<string, {
|
|
@@ -265,17 +265,17 @@ export declare const upstreamSchema: v.Type<v.UnrecognizedTuple | ["ackMutationR
|
|
|
265
265
|
clientID: string;
|
|
266
266
|
}] | ["changeDesiredQueries", {
|
|
267
267
|
desiredQueriesPatch: ({
|
|
268
|
+
op: "del";
|
|
269
|
+
hash: string;
|
|
270
|
+
} | {
|
|
271
|
+
op: "clear";
|
|
272
|
+
} | {
|
|
268
273
|
op: "put";
|
|
269
274
|
hash: string;
|
|
270
275
|
ttl?: number | undefined;
|
|
271
276
|
ast?: import("./ast.ts").AST | undefined;
|
|
272
277
|
name?: string | undefined;
|
|
273
278
|
args?: readonly import("../../shared/src/json.ts").ReadonlyJSONValue[] | undefined;
|
|
274
|
-
} | {
|
|
275
|
-
op: "del";
|
|
276
|
-
hash: string;
|
|
277
|
-
} | {
|
|
278
|
-
op: "clear";
|
|
279
279
|
})[];
|
|
280
280
|
traceparent?: string | undefined;
|
|
281
281
|
}] | ["closeConnection", unknown[]] | ["deleteClients", {
|
|
@@ -283,17 +283,17 @@ export declare const upstreamSchema: v.Type<v.UnrecognizedTuple | ["ackMutationR
|
|
|
283
283
|
readonly clientGroupIDs?: readonly string[] | undefined;
|
|
284
284
|
}] | ["initConnection", {
|
|
285
285
|
desiredQueriesPatch: ({
|
|
286
|
+
op: "del";
|
|
287
|
+
hash: string;
|
|
288
|
+
} | {
|
|
289
|
+
op: "clear";
|
|
290
|
+
} | {
|
|
286
291
|
op: "put";
|
|
287
292
|
hash: string;
|
|
288
293
|
ttl?: number | undefined;
|
|
289
294
|
ast?: import("./ast.ts").AST | undefined;
|
|
290
295
|
name?: string | undefined;
|
|
291
296
|
args?: readonly import("../../shared/src/json.ts").ReadonlyJSONValue[] | undefined;
|
|
292
|
-
} | {
|
|
293
|
-
op: "del";
|
|
294
|
-
hash: string;
|
|
295
|
-
} | {
|
|
296
|
-
op: "clear";
|
|
297
297
|
})[];
|
|
298
298
|
clientSchema?: {
|
|
299
299
|
tables: Record<string, {
|
|
@@ -397,17 +397,17 @@ export declare const upstreamSchemaWithUnparsedAnalyzeQuery: v.Type<v.Unrecogniz
|
|
|
397
397
|
clientID: string;
|
|
398
398
|
}] | ["changeDesiredQueries", {
|
|
399
399
|
desiredQueriesPatch: ({
|
|
400
|
+
op: "del";
|
|
401
|
+
hash: string;
|
|
402
|
+
} | {
|
|
403
|
+
op: "clear";
|
|
404
|
+
} | {
|
|
400
405
|
op: "put";
|
|
401
406
|
hash: string;
|
|
402
407
|
ttl?: number | undefined;
|
|
403
408
|
ast?: import("./ast.ts").AST | undefined;
|
|
404
409
|
name?: string | undefined;
|
|
405
410
|
args?: readonly import("../../shared/src/json.ts").ReadonlyJSONValue[] | undefined;
|
|
406
|
-
} | {
|
|
407
|
-
op: "del";
|
|
408
|
-
hash: string;
|
|
409
|
-
} | {
|
|
410
|
-
op: "clear";
|
|
411
411
|
})[];
|
|
412
412
|
traceparent?: string | undefined;
|
|
413
413
|
}] | ["closeConnection", unknown[]] | ["deleteClients", {
|
|
@@ -415,17 +415,17 @@ export declare const upstreamSchemaWithUnparsedAnalyzeQuery: v.Type<v.Unrecogniz
|
|
|
415
415
|
readonly clientGroupIDs?: readonly string[] | undefined;
|
|
416
416
|
}] | ["initConnection", {
|
|
417
417
|
desiredQueriesPatch: ({
|
|
418
|
+
op: "del";
|
|
419
|
+
hash: string;
|
|
420
|
+
} | {
|
|
421
|
+
op: "clear";
|
|
422
|
+
} | {
|
|
418
423
|
op: "put";
|
|
419
424
|
hash: string;
|
|
420
425
|
ttl?: number | undefined;
|
|
421
426
|
ast?: import("./ast.ts").AST | undefined;
|
|
422
427
|
name?: string | undefined;
|
|
423
428
|
args?: readonly import("../../shared/src/json.ts").ReadonlyJSONValue[] | undefined;
|
|
424
|
-
} | {
|
|
425
|
-
op: "del";
|
|
426
|
-
hash: string;
|
|
427
|
-
} | {
|
|
428
|
-
op: "clear";
|
|
429
429
|
})[];
|
|
430
430
|
clientSchema?: {
|
|
431
431
|
tables: Record<string, {
|
|
@@ -528,17 +528,17 @@ export declare const upstreamSchemaWithUnparsedAnalyzeQuery: v.Type<v.Unrecogniz
|
|
|
528
528
|
clientID: string;
|
|
529
529
|
}] | ["changeDesiredQueries", {
|
|
530
530
|
desiredQueriesPatch: ({
|
|
531
|
+
op: "del";
|
|
532
|
+
hash: string;
|
|
533
|
+
} | {
|
|
534
|
+
op: "clear";
|
|
535
|
+
} | {
|
|
531
536
|
op: "put";
|
|
532
537
|
hash: string;
|
|
533
538
|
ttl?: number | undefined;
|
|
534
539
|
ast?: import("./ast.ts").AST | undefined;
|
|
535
540
|
name?: string | undefined;
|
|
536
541
|
args?: readonly import("../../shared/src/json.ts").ReadonlyJSONValue[] | undefined;
|
|
537
|
-
} | {
|
|
538
|
-
op: "del";
|
|
539
|
-
hash: string;
|
|
540
|
-
} | {
|
|
541
|
-
op: "clear";
|
|
542
542
|
})[];
|
|
543
543
|
traceparent?: string | undefined;
|
|
544
544
|
}] | ["closeConnection", unknown[]] | ["deleteClients", {
|
|
@@ -546,17 +546,17 @@ export declare const upstreamSchemaWithUnparsedAnalyzeQuery: v.Type<v.Unrecogniz
|
|
|
546
546
|
readonly clientGroupIDs?: readonly string[] | undefined;
|
|
547
547
|
}] | ["initConnection", {
|
|
548
548
|
desiredQueriesPatch: ({
|
|
549
|
+
op: "del";
|
|
550
|
+
hash: string;
|
|
551
|
+
} | {
|
|
552
|
+
op: "clear";
|
|
553
|
+
} | {
|
|
549
554
|
op: "put";
|
|
550
555
|
hash: string;
|
|
551
556
|
ttl?: number | undefined;
|
|
552
557
|
ast?: import("./ast.ts").AST | undefined;
|
|
553
558
|
name?: string | undefined;
|
|
554
559
|
args?: readonly import("../../shared/src/json.ts").ReadonlyJSONValue[] | undefined;
|
|
555
|
-
} | {
|
|
556
|
-
op: "del";
|
|
557
|
-
hash: string;
|
|
558
|
-
} | {
|
|
559
|
-
op: "clear";
|
|
560
560
|
})[];
|
|
561
561
|
clientSchema?: {
|
|
562
562
|
tables: Record<string, {
|
|
@@ -658,17 +658,17 @@ export declare const upstreamSchemaWithUnparsedAnalyzeQuery: v.Type<v.Unrecogniz
|
|
|
658
658
|
clientID: string;
|
|
659
659
|
}] | ["changeDesiredQueries", {
|
|
660
660
|
desiredQueriesPatch: ({
|
|
661
|
+
op: "del";
|
|
662
|
+
hash: string;
|
|
663
|
+
} | {
|
|
664
|
+
op: "clear";
|
|
665
|
+
} | {
|
|
661
666
|
op: "put";
|
|
662
667
|
hash: string;
|
|
663
668
|
ttl?: number | undefined;
|
|
664
669
|
ast?: import("./ast.ts").AST | undefined;
|
|
665
670
|
name?: string | undefined;
|
|
666
671
|
args?: readonly import("../../shared/src/json.ts").ReadonlyJSONValue[] | undefined;
|
|
667
|
-
} | {
|
|
668
|
-
op: "del";
|
|
669
|
-
hash: string;
|
|
670
|
-
} | {
|
|
671
|
-
op: "clear";
|
|
672
672
|
})[];
|
|
673
673
|
traceparent?: string | undefined;
|
|
674
674
|
}] | ["closeConnection", unknown[]] | ["deleteClients", {
|
|
@@ -676,17 +676,17 @@ export declare const upstreamSchemaWithUnparsedAnalyzeQuery: v.Type<v.Unrecogniz
|
|
|
676
676
|
readonly clientGroupIDs?: readonly string[] | undefined;
|
|
677
677
|
}] | ["initConnection", {
|
|
678
678
|
desiredQueriesPatch: ({
|
|
679
|
+
op: "del";
|
|
680
|
+
hash: string;
|
|
681
|
+
} | {
|
|
682
|
+
op: "clear";
|
|
683
|
+
} | {
|
|
679
684
|
op: "put";
|
|
680
685
|
hash: string;
|
|
681
686
|
ttl?: number | undefined;
|
|
682
687
|
ast?: import("./ast.ts").AST | undefined;
|
|
683
688
|
name?: string | undefined;
|
|
684
689
|
args?: readonly import("../../shared/src/json.ts").ReadonlyJSONValue[] | undefined;
|
|
685
|
-
} | {
|
|
686
|
-
op: "del";
|
|
687
|
-
hash: string;
|
|
688
|
-
} | {
|
|
689
|
-
op: "clear";
|
|
690
690
|
})[];
|
|
691
691
|
clientSchema?: {
|
|
692
692
|
tables: Record<string, {
|
package/out/zql/src/ivm/cap.js
CHANGED
|
@@ -51,7 +51,7 @@ var Cap = class {
|
|
|
51
51
|
const capStateKey = getCapStateKey(this.#partitionKey, req.constraint);
|
|
52
52
|
const capState = this.#storage.get(capStateKey);
|
|
53
53
|
if (!capState) {
|
|
54
|
-
yield* this.#initialFetch(req);
|
|
54
|
+
yield* this.#initialFetch(req, capStateKey);
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
57
|
if (capState.size === 0) return;
|
|
@@ -70,11 +70,9 @@ var Cap = class {
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
*#initialFetch(req) {
|
|
73
|
+
*#initialFetch(req, capStateKey) {
|
|
74
74
|
if (this.#limit === 0) return;
|
|
75
75
|
assert(constraintMatchesPartitionKey(req.constraint, this.#partitionKey), "Constraint should match partition key");
|
|
76
|
-
const capStateKey = getCapStateKey(this.#partitionKey, req.constraint);
|
|
77
|
-
assert(this.#storage.get(capStateKey) === void 0, "Cap state should be undefined");
|
|
78
76
|
let size = 0;
|
|
79
77
|
const pks = [];
|
|
80
78
|
let downstreamEarlyReturn = true;
|
|
@@ -1 +1 @@
|
|
|
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 {emptyArray} from '../../../shared/src/sentinels.ts';\nimport type {Row, Value} from '../../../zero-protocol/src/data.ts';\nimport type {PrimaryKey} from '../../../zero-protocol/src/primary-key.ts';\nimport {ChangeIndex} from './change-index.ts';\nimport {ChangeType} from './change-type.ts';\nimport {makeAddChange, 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 InputBase,\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 destroy(): 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 // Cap is only built for non-flipped EXISTS subqueries, whose only\n // downstream consumer is a Join that always fetches with a constraint\n // built from the correlation's childField — which is Cap's partition\n // key. So either partitionKey is undefined, or constraint matches.\n assert(\n !this.#partitionKey ||\n (req.constraint !== undefined &&\n constraintMatchesPartitionKey(req.constraint, this.#partitionKey)),\n 'Cap fetch: constraint must match partition key when partitioned',\n );\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 pkConstraint = deserializePKToConstraint(pk, this.#primaryKey);\n // Preserve req.constraint (the partition key) so upstream partitioned\n // operators (e.g. Take) retain their partition scope and do not throw.\n const constraint = req.constraint\n ? {...req.constraint, ...pkConstraint}\n : pkConstraint;\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 }\n\n *#initialFetch(req: FetchRequest): Stream<Node | 'yield'> {\n if (this.#limit === 0) {\n return;\n }\n\n assert(\n constraintMatchesPartitionKey(req.constraint, this.#partitionKey),\n 'Constraint should match partition key',\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[ChangeIndex.TYPE] === ChangeType.EDIT) {\n yield* this.#pushEditChange(change);\n return;\n }\n\n const capStateKey = getCapStateKey(\n this.#partitionKey,\n change[ChangeIndex.NODE].row,\n );\n const capState = this.#storage.get(capStateKey);\n if (!capState) {\n return;\n }\n\n const pk = serializePK(change[ChangeIndex.NODE].row, this.#primaryKey);\n\n if (change[ChangeIndex.TYPE] === ChangeType.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[ChangeIndex.TYPE] === ChangeType.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(\n key => [key, change[ChangeIndex.NODE].row[key]] as const,\n ),\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(makeAddChange(replacement), this);\n } else {\n this.#storage.set(capStateKey, {size: newSize, pks});\n yield* this.#output.push(change, this);\n }\n } else if (change[ChangeIndex.TYPE] === ChangeType.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(\n change[ChangeIndex.OLD_NODE].row,\n change[ChangeIndex.NODE].row,\n ) === 0,\n 'Unexpected change of partition key',\n );\n const capStateKey = getCapStateKey(\n this.#partitionKey,\n change[ChangeIndex.OLD_NODE].row,\n );\n const capState = this.#storage.get(capStateKey);\n if (!capState) {\n return emptyArray;\n }\n\n const oldPK = serializePK(\n change[ChangeIndex.OLD_NODE].row,\n this.#primaryKey,\n );\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[ChangeIndex.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 return this.#output.push(change, this);\n }\n // If not in our set, drop\n return emptyArray;\n }\n\n destroy(): void {\n this.#input.destroy();\n this.#storage.destroy();\n }\n\n *reconcile(_pusher: InputBase): Stream<'yield'> {\n if (this.#output.reconcile) {\n yield* this.#output.reconcile(this);\n }\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":"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"}
|
|
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 {emptyArray} from '../../../shared/src/sentinels.ts';\nimport type {Row, Value} from '../../../zero-protocol/src/data.ts';\nimport type {PrimaryKey} from '../../../zero-protocol/src/primary-key.ts';\nimport {ChangeIndex} from './change-index.ts';\nimport {ChangeType} from './change-type.ts';\nimport {makeAddChange, 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 InputBase,\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 destroy(): 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 // Cap is only built for non-flipped EXISTS subqueries, whose only\n // downstream consumer is a Join that always fetches with a constraint\n // built from the correlation's childField — which is Cap's partition\n // key. So either partitionKey is undefined, or constraint matches.\n assert(\n !this.#partitionKey ||\n (req.constraint !== undefined &&\n constraintMatchesPartitionKey(req.constraint, this.#partitionKey)),\n 'Cap fetch: constraint must match partition key when partitioned',\n );\n\n const capStateKey = getCapStateKey(this.#partitionKey, req.constraint);\n const capState = this.#storage.get(capStateKey);\n if (!capState) {\n yield* this.#initialFetch(req, capStateKey);\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 pkConstraint = deserializePKToConstraint(pk, this.#primaryKey);\n // Preserve req.constraint (the partition key) so upstream partitioned\n // operators (e.g. Take) retain their partition scope and do not throw.\n const constraint = req.constraint\n ? {...req.constraint, ...pkConstraint}\n : pkConstraint;\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 }\n\n *#initialFetch(\n req: FetchRequest,\n capStateKey: string,\n ): Stream<Node | 'yield'> {\n if (this.#limit === 0) {\n return;\n }\n\n assert(\n constraintMatchesPartitionKey(req.constraint, this.#partitionKey),\n 'Constraint should match partition key',\n );\n\n // The caller (fetch) has already checked that there is no state for\n // capStateKey.\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[ChangeIndex.TYPE] === ChangeType.EDIT) {\n yield* this.#pushEditChange(change);\n return;\n }\n\n const capStateKey = getCapStateKey(\n this.#partitionKey,\n change[ChangeIndex.NODE].row,\n );\n const capState = this.#storage.get(capStateKey);\n if (!capState) {\n return;\n }\n\n const pk = serializePK(change[ChangeIndex.NODE].row, this.#primaryKey);\n\n if (change[ChangeIndex.TYPE] === ChangeType.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[ChangeIndex.TYPE] === ChangeType.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(\n key => [key, change[ChangeIndex.NODE].row[key]] as const,\n ),\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(makeAddChange(replacement), this);\n } else {\n this.#storage.set(capStateKey, {size: newSize, pks});\n yield* this.#output.push(change, this);\n }\n } else if (change[ChangeIndex.TYPE] === ChangeType.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(\n change[ChangeIndex.OLD_NODE].row,\n change[ChangeIndex.NODE].row,\n ) === 0,\n 'Unexpected change of partition key',\n );\n const capStateKey = getCapStateKey(\n this.#partitionKey,\n change[ChangeIndex.OLD_NODE].row,\n );\n const capState = this.#storage.get(capStateKey);\n if (!capState) {\n return emptyArray;\n }\n\n const oldPK = serializePK(\n change[ChangeIndex.OLD_NODE].row,\n this.#primaryKey,\n );\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[ChangeIndex.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 return this.#output.push(change, this);\n }\n // If not in our set, drop\n return emptyArray;\n }\n\n destroy(): void {\n this.#input.destroy();\n this.#storage.destroy();\n }\n\n *reconcile(_pusher: InputBase): Stream<'yield'> {\n if (this.#output.reconcile) {\n yield* this.#output.reconcile(this);\n }\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":"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"}
|