Experimental Document Splitting - Agrejus/pouchdb-entity-fabric GitHub Wiki

Motivation: Documents cannot be fully removed from PouchDB

Experimental Document Splitting allows for full removal of a document. To get started, we need to use the ExperimentalDataContext, instead of the regular DataContext

Managed Split

After we call saveChanges the referece property will be split into a separate database, which will be destroyed when the database has no documents remaining. Documents are added to a new PouchDB database per transaction. A transaction is started when saveChanges is called and the transaction is ended and a new one created when documents are removed from the split DbSet.


enum DocumentTypes {
    Notes = "Notes",
    Books = "Books",
    Cars = "Cars",
}

interface INote extends IDbRecord<DocumentTypes> {
    contents: string;
    createdDate: string;
    userId: string;
}

interface IBook extends ISplitDbRecord<DocumentTypes, DocumentTypes, INote> {
    author: string;
    publishDate?: string;
    rejectedCount: number;
    status: "pending" | "approved" | "rejected";
    syncStatus: "pending" | "approved" | "rejected";
}

export class PouchDbDataContext extends ExperimentalDataContext<DocumentTypes> {
    books = this.experimentalDbset().split<DocumentTypes, INote, IBook>(DocumentTypes.Books).create();
}

const context = new PouchDbDataContext();

await context.books.add({
    author: "James",
    reference: {
        contents: "Note Contents",
        createdDate: "some date",
        userId: "some user id"
    },
    rejectedCount: 1,
    status: "pending",
    syncStatus: "approved"
});

await context.saveChanges();

Unmanaged Split

An unmanaged split DbSet is like a split DbSet, except it does not manage the changes of the reference. It can only retrieve them, not save them


enum DocumentTypes {
    Notes = "Notes",
    Books = "Books",
    Cars = "Cars",
}

interface INote extends IDbRecord<DocumentTypes> {
    contents: string;
    createdDate: string;
    userId: string;
}

interface IBook extends ISplitDbRecord<DocumentTypes, DocumentTypes, INote> {
    author: string;
    publishDate?: string;
    rejectedCount: number;
    status: "pending" | "approved" | "rejected";
    syncStatus: "pending" | "approved" | "rejected";
}

export class PouchDbDataContext extends ExperimentalDataContext<DocumentTypes> {
    books = this.experimentalDbset().unmanagedSplit<DocumentTypes, INote, IBook>(DocumentTypes.Books).create();
}

const context = new PouchDbDataContext();

await context.books.add({
    author: "James",
    referencePath: "Some Reference Path",
    rejectedCount: 1,
    status: "pending",
    syncStatus: "approved"
});

await context.saveChanges();