Skip to main content
Manage persistent state across tasks and task runs using mongo-like collections operations. Often your application will have a notion of some sort of stored state, collections are where this state can be stored, then updated, searched and filtered from any task at any time. Collections are built on postgres, and each compose app has it’s own fully isolated postgres database which stores collections data as well as other internal compose data for your app, so you can store even the most important state in a tried and true database.

Examples

/// <reference types="../../.compose/types.d.ts" /> 

type Dog = {
  breed: string;
  color: string;
}

export async function main({ collection }) {
  const dogsCollection = await collection<Dog>("dogs", {
    indexes: [
      { path: "color", type: "text" },
    ],
  });

  // Get existing state
  const allDogs = await dogsCollection.list({ offset: 0, limit: 20 });
  const brownDogs = await dogsCollection.findMany({ color: "brown" });

  // Get some data
  const newData = await fetch<Dog>("https://api.dogs.com/v1/dogs/labrador");

  // Update state
  await dogsCollection.insertOne(newData);

  return {
    success: true,
  };
}

Full Interface

export type ScalarIndexType = 
    "text" | 
    "numeric" | 
    "boolean" | 
    "timestamptz"; //  (timestamp with time zone)

export interface CollectionIndex {
  path: string;             
  type: ScalarIndexType;      
  unique?: boolean;
}

export interface FindOptions {
  limit?: number;
  offset?: number;
}
export type Filter = Record<string, string | unknown>;
export type WithId<T> = T & { id: string };

export interface Collection<TDoc = unknown> {
  readonly name: string;
  insertOne(doc: TDoc, opts?: { id?: string }): Promise<{ id: string }>;
  findOne(filter: Filter): Promise<WithId<TDoc> | null>;
  findMany(filter: Filter, options?: FindOptions): Promise<Array<WithId<TDoc>>>;
  list(options?: FindOptions): Promise<Array<WithId<TDoc>>>;
  getById(id: string): Promise<WithId<TDoc> | null>;
  setById(id: string, doc: TDoc, opts?: { upsert?: boolean }): Promise<{ id: string; upserted?: boolean; matched?: number }>;
  deleteById(id: string): Promise<{ deletedCount: number }>;
  createScalarIndex(index: CollectionIndex): Promise<void>;
  drop(): Promise<void>;
}

context: {
  collection: (name: string, options?: { indexes?: CollectionIndex[] }) => Promise<Collection>;
}

Next Steps