@@ -147,6 +147,26 @@ export type SearchIndex = {
147147 searchField : string ;
148148 filterFields : string [ ] ;
149149} ;
150+
151+ /**
152+ * Options for defining an index.
153+ *
154+ * @public
155+ */
156+ export interface IndexOptions {
157+ /**
158+ * Whether the index should be staged.
159+ *
160+ * For large tables, index backfill can be slow. Staging an index allows you
161+ * to push the schema and enable the index later.
162+ *
163+ * If `staged` is `true`, the index will be staged and will not be enabled
164+ * until the staged flag is removed. Staged indexes do not block push
165+ * completion. Staged indexes cannot be used in queries.
166+ */
167+ staged ?: boolean ;
168+ }
169+
150170/**
151171 * The definition of a table within a schema.
152172 *
@@ -210,10 +230,9 @@ export class TableDefinition<
210230 > (
211231 name : IndexName ,
212232 fields : [ FirstFieldPath , ...RestFieldPaths ] ,
233+ options ?: IndexOptions & { staged : false } ,
213234 ) : TableDefinition <
214235 DocumentType ,
215- // Update `Indexes` to include the new index and use `Expand` to make the
216- // types look pretty in editors.
217236 Expand <
218237 Indexes &
219238 Record <
@@ -223,28 +242,49 @@ export class TableDefinition<
223242 > ,
224243 SearchIndexes ,
225244 VectorIndexes
226- > {
227- this . indexes . push ( { indexDescriptor : name , fields } ) ;
228- return this ;
229- }
245+ > ;
230246
231247 /**
248+ * Define a staged index on this table.
232249 *
233- * @internal
234- * @param name - The name of the staged index.
250+ * For large tables, index backfill can be slow. Staging an index allows you
251+ * to push the schema and enable the index later.
252+ *
253+ * If `staged` is `true`, the index will be staged and will not be enabled
254+ * until the staged flag is removed. Staged indexes do not block push
255+ * completion. Staged indexes cannot be used in queries.
256+ *
257+ * To learn about indexes, see [Defining Indexes](https://docs.convex.dev/using/indexes).
258+ *
259+ * @param name - The name of the index.
235260 * @param fields - The fields to index, in order. Must specify at least one
236261 * field.
237- * @returns A {@link TableDefinition} with this staged index included.
262+ * @returns A {@link TableDefinition} with this index included.
238263 */
239- stagedIndex <
264+ index <
265+ IndexName extends string ,
266+ FirstFieldPath extends ExtractFieldPaths < DocumentType > ,
267+ RestFieldPaths extends ExtractFieldPaths < DocumentType > [ ] ,
268+ > (
269+ name : IndexName ,
270+ fields : [ FirstFieldPath , ...RestFieldPaths ] ,
271+ options : IndexOptions & { staged : true } ,
272+ ) : TableDefinition < DocumentType , Indexes , SearchIndexes , VectorIndexes > ;
273+
274+ index <
240275 IndexName extends string ,
241276 FirstFieldPath extends ExtractFieldPaths < DocumentType > ,
242277 RestFieldPaths extends ExtractFieldPaths < DocumentType > [ ] ,
243278 > (
244279 name : IndexName ,
245280 fields : [ FirstFieldPath , ...RestFieldPaths ] ,
246- ) : TableDefinition < DocumentType , Indexes , SearchIndexes , VectorIndexes > {
247- this . stagedDbIndexes . push ( { indexDescriptor : name , fields } ) ;
281+ options ?: IndexOptions ,
282+ ) {
283+ if ( options ?. staged ) {
284+ this . stagedDbIndexes . push ( { indexDescriptor : name , fields } ) ;
285+ } else {
286+ this . indexes . push ( { indexDescriptor : name , fields } ) ;
287+ }
248288 return this ;
249289 }
250290
@@ -263,7 +303,10 @@ export class TableDefinition<
263303 FilterFields extends ExtractFieldPaths < DocumentType > = never ,
264304 > (
265305 name : IndexName ,
266- indexConfig : Expand < SearchIndexConfig < SearchField , FilterFields > > ,
306+ indexConfig : Expand <
307+ SearchIndexConfig < SearchField , FilterFields > &
308+ IndexOptions & { staged ?: false }
309+ > ,
267310 ) : TableDefinition <
268311 DocumentType ,
269312 Indexes ,
@@ -280,38 +323,59 @@ export class TableDefinition<
280323 >
281324 > ,
282325 VectorIndexes
283- > {
284- this . searchIndexes . push ( {
285- indexDescriptor : name ,
286- searchField : indexConfig . searchField ,
287- filterFields : indexConfig . filterFields || [ ] ,
288- } ) ;
289- return this ;
290- }
326+ > ;
291327
292328 /**
293- * Stage a search index on this table.
329+ * Define a staged search index on this table.
294330 *
295- * To learn about text search indexes, see [Search](https://docs.convex.dev/text-search).
331+ * For large tables, index backfill can be slow. Staging an index allows you
332+ * to push the schema and enable the index later.
333+ *
334+ * If `staged` is `true`, the index will be staged and will not be enabled
335+ * until the staged flag is removed. Staged indexes do not block push
336+ * completion. Staged indexes cannot be used in queries.
337+ *
338+ * To learn about search indexes, see [Search](https://docs.convex.dev/text-search).
296339 *
297- * @internal
298340 * @param name - The name of the index.
299- * @param indexConfig - The text index configuration object.
300- * @returns A {@link TableDefinition} with this text index included.
341+ * @param indexConfig - The search index configuration object.
342+ * @returns A {@link TableDefinition} with this search index included.
301343 */
302- stagedSearchIndex <
344+ searchIndex <
303345 IndexName extends string ,
304346 SearchField extends ExtractFieldPaths < DocumentType > ,
305347 FilterFields extends ExtractFieldPaths < DocumentType > = never ,
306348 > (
307349 name : IndexName ,
308- indexConfig : Expand < SearchIndexConfig < SearchField , FilterFields > > ,
309- ) : TableDefinition < DocumentType , Indexes , SearchIndexes , VectorIndexes > {
310- this . stagedSearchIndexes . push ( {
311- indexDescriptor : name ,
312- searchField : indexConfig . searchField ,
313- filterFields : indexConfig . filterFields || [ ] ,
314- } ) ;
350+ indexConfig : Expand <
351+ SearchIndexConfig < SearchField , FilterFields > &
352+ IndexOptions & { staged : true }
353+ > ,
354+ ) : TableDefinition < DocumentType , Indexes , SearchIndexes , VectorIndexes > ;
355+
356+ searchIndex <
357+ IndexName extends string ,
358+ SearchField extends ExtractFieldPaths < DocumentType > ,
359+ FilterFields extends ExtractFieldPaths < DocumentType > = never ,
360+ > (
361+ name : IndexName ,
362+ indexConfig : Expand <
363+ SearchIndexConfig < SearchField , FilterFields > & IndexOptions
364+ > ,
365+ ) {
366+ if ( indexConfig . staged ) {
367+ this . stagedSearchIndexes . push ( {
368+ indexDescriptor : name ,
369+ searchField : indexConfig . searchField ,
370+ filterFields : indexConfig . filterFields || [ ] ,
371+ } ) ;
372+ } else {
373+ this . searchIndexes . push ( {
374+ indexDescriptor : name ,
375+ searchField : indexConfig . searchField ,
376+ filterFields : indexConfig . filterFields || [ ] ,
377+ } ) ;
378+ }
315379 return this ;
316380 }
317381
@@ -330,7 +394,10 @@ export class TableDefinition<
330394 FilterFields extends ExtractFieldPaths < DocumentType > = never ,
331395 > (
332396 name : IndexName ,
333- indexConfig : Expand < VectorIndexConfig < VectorField , FilterFields > > ,
397+ indexConfig : Expand <
398+ VectorIndexConfig < VectorField , FilterFields > &
399+ IndexOptions & { staged ?: false }
400+ > ,
334401 ) : TableDefinition <
335402 DocumentType ,
336403 Indexes ,
@@ -346,40 +413,61 @@ export class TableDefinition<
346413 }
347414 >
348415 >
349- > {
350- this . vectorIndexes . push ( {
351- indexDescriptor : name ,
352- vectorField : indexConfig . vectorField ,
353- dimensions : indexConfig . dimensions ,
354- filterFields : indexConfig . filterFields || [ ] ,
355- } ) ;
356- return this ;
357- }
416+ > ;
358417
359418 /**
360- * Stage a vector index on this table.
419+ * Define a staged vector index on this table.
420+ *
421+ * For large tables, index backfill can be slow. Staging an index allows you
422+ * to push the schema and enable the index later.
423+ *
424+ * If `staged` is `true`, the index will be staged and will not be enabled
425+ * until the staged flag is removed. Staged indexes do not block push
426+ * completion. Staged indexes cannot be used in queries.
361427 *
362428 * To learn about vector indexes, see [Vector Search](https://docs.convex.dev/vector-search).
363429 *
364- * @internal
365430 * @param name - The name of the index.
366431 * @param indexConfig - The vector index configuration object.
367432 * @returns A {@link TableDefinition} with this vector index included.
368433 */
369- stagedVectorIndex <
434+ vectorIndex <
370435 IndexName extends string ,
371436 VectorField extends ExtractFieldPaths < DocumentType > ,
372437 FilterFields extends ExtractFieldPaths < DocumentType > = never ,
373438 > (
374439 name : IndexName ,
375- indexConfig : Expand < VectorIndexConfig < VectorField , FilterFields > > ,
376- ) : TableDefinition < DocumentType , Indexes , SearchIndexes , VectorIndexes > {
377- this . stagedVectorIndexes . push ( {
378- indexDescriptor : name ,
379- vectorField : indexConfig . vectorField ,
380- dimensions : indexConfig . dimensions ,
381- filterFields : indexConfig . filterFields || [ ] ,
382- } ) ;
440+ indexConfig : Expand <
441+ VectorIndexConfig < VectorField , FilterFields > &
442+ IndexOptions & { staged : true }
443+ > ,
444+ ) : TableDefinition < DocumentType , Indexes , SearchIndexes , VectorIndexes > ;
445+
446+ vectorIndex <
447+ IndexName extends string ,
448+ VectorField extends ExtractFieldPaths < DocumentType > ,
449+ FilterFields extends ExtractFieldPaths < DocumentType > = never ,
450+ > (
451+ name : IndexName ,
452+ indexConfig : Expand <
453+ VectorIndexConfig < VectorField , FilterFields > & IndexOptions
454+ > ,
455+ ) {
456+ if ( indexConfig . staged ) {
457+ this . stagedVectorIndexes . push ( {
458+ indexDescriptor : name ,
459+ vectorField : indexConfig . vectorField ,
460+ dimensions : indexConfig . dimensions ,
461+ filterFields : indexConfig . filterFields || [ ] ,
462+ } ) ;
463+ } else {
464+ this . vectorIndexes . push ( {
465+ indexDescriptor : name ,
466+ vectorField : indexConfig . vectorField ,
467+ dimensions : indexConfig . dimensions ,
468+ filterFields : indexConfig . filterFields || [ ] ,
469+ } ) ;
470+ }
383471 return this ;
384472 }
385473
0 commit comments