Skip to content

Commit 614bb98

Browse files
committed
Variadic get, fixes #7
1 parent 5b48aa9 commit 614bb98

File tree

6 files changed

+168
-68
lines changed

6 files changed

+168
-68
lines changed

docs/pages/read.mdx

+22-7
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,23 @@ const task = await ctx.db
5656

5757
</Aside>
5858

59+
## Reading a single ent via a compound index
60+
61+
```ts
62+
const task = await ctx.table("users").get("nameAndRank", "Steve", 10);
63+
```
64+
65+
<Aside title="This is equivalent to the built-in:">
66+
67+
```ts
68+
const task = await ctx.db
69+
.query("users")
70+
.withIndex("nameAndRank", (q) => q.eq("name", "Steve").eq("rank", 10))
71+
.unique();
72+
```
73+
74+
</Aside>
75+
5976
## Reading a single ent or throwing
6077

6178
The `getX` method (pronounced "get or throw") throws an `Error` if the read
@@ -118,7 +135,7 @@ index name and filter callback to `ctx.table`:
118135

119136
```ts
120137
const posts = await ctx.table("posts", "numLikes", (q) =>
121-
q.gt("numLikes", 100)
138+
q.gt("numLikes", 100),
122139
);
123140
```
124141

@@ -329,7 +346,7 @@ const hasTag =
329346
(await ctx.db
330347
.query("messages_to_tags")
331348
.withIndex("messagesId", (q) =>
332-
q.eq("messagesId", message._id).eq("tagsId", tagId)
349+
q.eq("messagesId", message._id).eq("tagsId", tagId),
333350
)
334351
.first()) !== null;
335352
```
@@ -369,9 +386,7 @@ functionality:">
369386

370387
```ts
371388
const usersWithMessagesAndProfile = await Promise.all(
372-
(
373-
await ctx.db.query("users").collect()
374-
).map(async (user) => ({
389+
(await ctx.db.query("users").collect()).map(async (user) => ({
375390
name: user.name,
376391
posts: await ctx.db
377392
.query("messages")
@@ -384,12 +399,12 @@ const usersWithMessagesAndProfile = await Promise.all(
384399
.unique();
385400
if (profile === null) {
386401
throw new Error(
387-
`Edge "profile" does not exist for document wit ID "${user._id}"`
402+
`Edge "profile" does not exist for document wit ID "${user._id}"`,
388403
);
389404
}
390405
return profile;
391406
})(),
392-
}))
407+
})),
393408
);
394409
```
395410

package-lock.json

+109-15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,6 @@
3535
"eslint": "8.49.0",
3636
"npm-run-all": "^4.1.5",
3737
"tsup": "^8.0.1",
38-
"typescript": "^5.3.3"
38+
"typescript": "^5.4.0"
3939
}
4040
}

src/functions.ts

+19-32
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,6 @@ import {
4242
} from "./writer";
4343
import { ScheduledDeleteFuncRef } from "./deletion";
4444

45-
// TODO: Figure out how to make get() variadic
46-
// type FieldTypes<
47-
//
48-
// Table extends TableNamesInDataModel<EntsDataModel>,
49-
// T extends string[]
50-
// > = {
51-
// [K in keyof T]: FieldTypeFromFieldPath<
52-
// DocumentByName<EntsDataModel, Table>,
53-
// T[K]
54-
// >;
55-
// };
56-
5745
export interface PromiseOrderedQueryOrNull<
5846
EntsDataModel extends GenericEntsDataModel,
5947
Table extends TableNamesInDataModel<EntsDataModel>,
@@ -147,11 +135,7 @@ export interface PromiseTable<
147135
Index extends keyof Indexes,
148136
>(
149137
indexName: Index,
150-
// TODO: Figure out how to make this variadic
151-
value0: FieldTypeFromFieldPath<
152-
DocumentByName<EntsDataModel, Table>,
153-
Indexes[Index][0]
154-
>,
138+
...values: IndexFieldTypesForEq<EntsDataModel, Table, Indexes[Index]>
155139
): PromiseEntOrNull<EntsDataModel, Table>;
156140
get(id: GenericId<Table>): PromiseEntOrNull<EntsDataModel, Table>;
157141
/**
@@ -162,11 +146,7 @@ export interface PromiseTable<
162146
Index extends keyof Indexes,
163147
>(
164148
indexName: Index,
165-
// TODO: Figure out how to make this variadic
166-
value0: FieldTypeFromFieldPath<
167-
DocumentByName<EntsDataModel, Table>,
168-
Indexes[Index][0]
169-
>,
149+
...values: IndexFieldTypesForEq<EntsDataModel, Table, Indexes[Index]>
170150
): PromiseEnt<EntsDataModel, Table>;
171151
/**
172152
* Fetch a document from the DB for a given ID, throw if it doesn't exist.
@@ -1756,11 +1736,7 @@ export interface PromiseTableWriter<
17561736
Index extends keyof Indexes,
17571737
>(
17581738
indexName: Index,
1759-
// TODO: Figure out how to make this variadic
1760-
value0: FieldTypeFromFieldPath<
1761-
DocumentByName<EntsDataModel, Table>,
1762-
Indexes[Index][0]
1763-
>,
1739+
...values: IndexFieldTypesForEq<EntsDataModel, Table, Indexes[Index]>
17641740
): PromiseEntWriterOrNull<EntsDataModel, Table>;
17651741
get(id: GenericId<Table>): PromiseEntWriterOrNull<EntsDataModel, Table>;
17661742
/**
@@ -1771,11 +1747,7 @@ export interface PromiseTableWriter<
17711747
Index extends keyof Indexes,
17721748
>(
17731749
indexName: Index,
1774-
// TODO: Figure out how to make this variadic
1775-
value0: FieldTypeFromFieldPath<
1776-
DocumentByName<EntsDataModel, Table>,
1777-
Indexes[Index][0]
1778-
>,
1750+
...values: IndexFieldTypesForEq<EntsDataModel, Table, Indexes[Index]>
17791751
): PromiseEntWriter<EntsDataModel, Table>;
17801752
/**
17811753
* Fetch a document from the DB for a given ID, throw if it doesn't exist.
@@ -2369,6 +2341,21 @@ const nullRetriever = {
23692341
doc: async () => null,
23702342
};
23712343

2344+
type IndexFieldTypesForEq<
2345+
EntsDataModel extends GenericEntsDataModel,
2346+
Table extends TableNamesInDataModel<EntsDataModel>,
2347+
T extends string[],
2348+
> = Pop<{
2349+
[K in keyof T]: FieldTypeFromFieldPath<
2350+
DocumentByName<EntsDataModel, Table>,
2351+
T[K]
2352+
>;
2353+
}>;
2354+
2355+
type Pop<T extends any[]> = T extends [...infer Rest, infer _Last]
2356+
? Rest
2357+
: never;
2358+
23722359
// function idRetriever<
23732360
// DataModel extends GenericDataModel,
23742361
// Table extends TableNamesInDataModel<DataModel>

src/schema.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ export interface EntDefinition<
527527
): EntDefinition<
528528
Document & ObjectFieldType<FieldName, T>,
529529
FieldPaths | FieldName,
530-
Indexes & { [key in FieldName]: [FieldName] },
530+
Indexes & { [key in FieldName]: [FieldName, "_creationTime"] },
531531
SearchIndexes,
532532
VectorIndexes,
533533
Edges
@@ -539,7 +539,7 @@ export interface EntDefinition<
539539
): EntDefinition<
540540
Document & ObjectFieldType<FieldName, T>,
541541
FieldPaths | FieldName,
542-
Indexes & { [key in FieldName]: [FieldName] },
542+
Indexes & { [key in FieldName]: [FieldName, "_creationTime"] },
543543
SearchIndexes,
544544
VectorIndexes,
545545
Edges
@@ -562,7 +562,7 @@ export interface EntDefinition<
562562
): EntDefinition<
563563
Document & { [key in `${EdgeName}Id`]: GenericId<`${EdgeName}s`> },
564564
FieldPaths | `${EdgeName}Id`,
565-
Indexes & { [key in `${EdgeName}Id`]: [`${EdgeName}Id`] },
565+
Indexes & { [key in `${EdgeName}Id`]: [`${EdgeName}Id`, "_creationTime"] },
566566
SearchIndexes,
567567
VectorIndexes,
568568
Edges & {
@@ -580,7 +580,9 @@ export interface EntDefinition<
580580
): EntDefinition<
581581
Document & { [key in NoInfer<FieldName>]: GenericId<`${EdgeName}s`> },
582582
FieldPaths | NoInfer<FieldName>,
583-
Indexes & { [key in NoInfer<FieldName>]: [NoInfer<FieldName>] },
583+
Indexes & {
584+
[key in NoInfer<FieldName>]: [NoInfer<FieldName>, "_creationTime"];
585+
},
584586
SearchIndexes,
585587
VectorIndexes,
586588
Edges & {
@@ -602,7 +604,9 @@ export interface EntDefinition<
602604
): EntDefinition<
603605
Document & { [key in NoInfer<FieldName>]: GenericId<ToTable> },
604606
FieldPaths | NoInfer<FieldName>,
605-
Indexes & { [key in NoInfer<FieldName>]: [NoInfer<FieldName>] },
607+
Indexes & {
608+
[key in NoInfer<FieldName>]: [NoInfer<FieldName>, "_creationTime"];
609+
},
606610
SearchIndexes,
607611
VectorIndexes,
608612
Edges & {

0 commit comments

Comments
 (0)