@davidtkramer/convex-relations 0.6.0 → 0.6.2
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/README.md +12 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.js +18 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -401,9 +401,20 @@ const posts = await q.posts.in(postIds).many();
|
|
|
401
401
|
const categories = await q.categories.bySlug
|
|
402
402
|
.in(["typescript", "convex"])
|
|
403
403
|
.many();
|
|
404
|
+
|
|
405
|
+
// Compound indexes take positional prefixes, one tuple per lookup. A bare
|
|
406
|
+
// value is the one-argument call on the leading field.
|
|
407
|
+
const comments = await q.comments.byPostIdAndStatus
|
|
408
|
+
.in([
|
|
409
|
+
[postId, "approved"],
|
|
410
|
+
[otherPostId, "pending"],
|
|
411
|
+
thirdPostId,
|
|
412
|
+
])
|
|
413
|
+
.many();
|
|
404
414
|
```
|
|
405
415
|
|
|
406
|
-
|
|
416
|
+
Each value runs as its own index query, in parallel; results are concatenated
|
|
417
|
+
in list order. Batch lookups skip missing rows and dedupe the values.
|
|
407
418
|
|
|
408
419
|
## Relation Expansion with `with(...)`
|
|
409
420
|
|
package/dist/index.d.ts
CHANGED
|
@@ -38,7 +38,11 @@ type PositionalIndexArgs<DataModel extends GenericDataModel, Table extends AppTa
|
|
|
38
38
|
type RootIndexValueArg<DataModel extends GenericDataModel, Table extends AppTable<DataModel>, IndexName extends UserIndex<DataModel, Table>> = PositionalIndexArgs<DataModel, Table, IndexName> | (SingleIndexField<DataModel, Table, IndexName> extends never ? never : DocFieldType<AppDoc<DataModel, Table>, SingleIndexField<DataModel, Table, IndexName>>);
|
|
39
39
|
type StrictRootIndexValueArg<DataModel extends GenericDataModel, Table extends AppTable<DataModel>, IndexName extends UserIndex<DataModel, Table>, Value extends RootIndexValueArg<DataModel, Table, IndexName>> = Value;
|
|
40
40
|
type TableIndexName<DataModel extends GenericDataModel, Table extends AppTable<DataModel>> = UserIndex<DataModel, Table> | 'by_id';
|
|
41
|
-
type
|
|
41
|
+
type FirstIndexField<DataModel extends GenericDataModel, Table extends AppTable<DataModel>, IndexName extends UserIndex<DataModel, Table>> = UserIndexFields<DataModel, Table, IndexName> extends readonly [
|
|
42
|
+
infer Field extends string,
|
|
43
|
+
...unknown[]
|
|
44
|
+
] ? Field : never;
|
|
45
|
+
type UserIndexArg<DataModel extends GenericDataModel, Table extends AppTable<DataModel>, IndexName extends UserIndex<DataModel, Table>> = DocFieldType<AppDoc<DataModel, Table>, FirstIndexField<DataModel, Table, IndexName>> | PositionalIndexArgs<DataModel, Table, IndexName> | Readonly<PositionalIndexArgs<DataModel, Table, IndexName>>;
|
|
42
46
|
type TableIndexValueArg<DataModel extends GenericDataModel, Table extends AppTable<DataModel>, IndexName extends TableIndexName<DataModel, Table>> = IndexName extends 'by_id' ? GenericId<Table> : IndexName extends UserIndex<DataModel, Table> ? UserIndexArg<DataModel, Table, IndexName> : never;
|
|
43
47
|
type StrictTableIndexValueArg<DataModel extends GenericDataModel, Table extends AppTable<DataModel>, IndexName extends TableIndexName<DataModel, Table>, Value extends TableIndexValueArg<DataModel, Table, IndexName>> = Value;
|
|
44
48
|
type TableIndexInvocationArgs<DataModel extends GenericDataModel, Table extends AppTable<DataModel>, IndexName extends TableIndexName<DataModel, Table>> = IndexName extends 'by_id' ? [GenericId<Table>] : IndexName extends UserIndex<DataModel, Table> ? PositionalIndexArgs<DataModel, Table, IndexName> : never;
|
|
@@ -150,7 +154,7 @@ type ThroughCollectionSource<DataModel extends GenericDataModel, SourceTable ext
|
|
|
150
154
|
type TableNamespace<DataModel extends GenericDataModel, Table extends AppTable<DataModel>> = {
|
|
151
155
|
find<const Id extends GenericId<Table>>(id: Id): FindQueryBuilder<AppDoc<DataModel, Table>>;
|
|
152
156
|
findOrNull<const Id extends GenericId<Table>>(id: Id): FindOrNullQueryBuilder<AppDoc<DataModel, Table>>;
|
|
153
|
-
in<const Id extends GenericId<Table>>(ids: Id[]): TableBatchQueryFacade<DataModel, Table>;
|
|
157
|
+
in<const Id extends GenericId<Table>>(ids: readonly Id[]): TableBatchQueryFacade<DataModel, Table>;
|
|
154
158
|
withIndex<const IndexName extends UserIndex<DataModel, Table>>(index: IndexName, selector: IndexSelector<DataModel, Table, IndexName>): TableQueryFacade<DataModel, Table>;
|
|
155
159
|
withIndex<const IndexName extends UserIndex<DataModel, Table>>(index: IndexName): TableRangeQueryFacade<DataModel, Table>;
|
|
156
160
|
through: {
|
|
@@ -164,7 +168,7 @@ type TableNamespace<DataModel extends GenericDataModel, Table extends AppTable<D
|
|
|
164
168
|
(selector: IndexName extends UserIndex<DataModel, Table> ? IndexSelector<DataModel, Table, IndexName> : never): TableQueryFacade<DataModel, Table>;
|
|
165
169
|
<const Args extends TableIndexInvocationArgs<DataModel, Table, IndexName>>(...args: Args): TableQueryFacade<DataModel, Table, NarrowedIndexItem<DataModel, Table, IndexName, Args>>;
|
|
166
170
|
(): TableRangeQueryFacade<DataModel, Table>;
|
|
167
|
-
in<const Value extends TableIndexValueArg<DataModel, Table, IndexName>>(values: StrictTableIndexValueArg<DataModel, Table, IndexName, Value>[]): TableBatchQueryFacade<DataModel, Table, NarrowedIndexItem<DataModel, Table, IndexName, Value extends readonly unknown[] ? Value : [Value]>>;
|
|
171
|
+
in<const Value extends TableIndexValueArg<DataModel, Table, IndexName>>(values: readonly StrictTableIndexValueArg<DataModel, Table, IndexName, Value>[]): TableBatchQueryFacade<DataModel, Table, NarrowedIndexItem<DataModel, Table, IndexName, Value extends readonly unknown[] ? Value : [Value]>>;
|
|
168
172
|
};
|
|
169
173
|
};
|
|
170
174
|
type QueryFacade<DataModel extends GenericDataModel> = {
|
package/dist/index.js
CHANGED
|
@@ -630,10 +630,27 @@ function createBatchPlan(table, index, values, indexFields) {
|
|
|
630
630
|
kind: "batch",
|
|
631
631
|
table,
|
|
632
632
|
index,
|
|
633
|
-
values,
|
|
633
|
+
values: uniqueBatchValues(values),
|
|
634
634
|
indexFields
|
|
635
635
|
});
|
|
636
636
|
}
|
|
637
|
+
function uniqueBatchValues(values) {
|
|
638
|
+
const seenScalars = /* @__PURE__ */ new Set();
|
|
639
|
+
const seenTuples = [];
|
|
640
|
+
return values.filter((value) => {
|
|
641
|
+
if (!Array.isArray(value)) {
|
|
642
|
+
if (seenScalars.has(value)) return false;
|
|
643
|
+
seenScalars.add(value);
|
|
644
|
+
return true;
|
|
645
|
+
}
|
|
646
|
+
if (seenTuples.some((other) => sameBatchValue(other, value))) return false;
|
|
647
|
+
seenTuples.push(value);
|
|
648
|
+
return true;
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
function sameBatchValue(a, b) {
|
|
652
|
+
return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((item, index) => Object.is(item, b[index]));
|
|
653
|
+
}
|
|
637
654
|
function isCollectionSource(value) {
|
|
638
655
|
return typeof value === "object" && value !== null && "_plan" in value && "_table" in value;
|
|
639
656
|
}
|