Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
Move Workspace implementation to AdapterWorkspace
Browse files Browse the repository at this point in the history
- Move Adapter<C> interface to meta/pouch/types
- Add meta/pouch/workspace module with AdapterWorkspace<C> class, which
  accepts an Adapter<C> and implements Workspace<C>
  • Loading branch information
g. nicholas d'andrea committed May 15, 2021
1 parent 46c899f commit efb7629
Show file tree
Hide file tree
Showing 4 changed files with 236 additions and 194 deletions.
194 changes: 5 additions & 189 deletions packages/db/src/meta/pouch/adapters/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,50 +8,21 @@ import PouchDBFind from "pouchdb-find";
import type {
CollectionName,
Collections,
MutationInput,
MutationPayload,
MutableCollectionName,
Input,
SavedInput
} from "@truffle/db/meta/collections";
import * as Id from "@truffle/db/meta/id";
import type { Historical } from "@truffle/db/meta/data";

import type { Definition, Definitions } from "@truffle/db/meta/pouch/types";
import type {
Adapter,
Definition,
Definitions
} from "@truffle/db/meta/pouch/types";

export interface DatabasesOptions<C extends Collections> {
definitions: Definitions<C>;
settings: any;
}

export interface Adapter<C extends Collections> {
every<N extends CollectionName<C>, I extends { id: string }>(
collectionName: N
): Promise<Historical<I>[]>;

retrieve<N extends CollectionName<C>, I extends { id: string }>(
collectionName: N,
references: (Pick<I, "id"> | undefined)[]
): Promise<(Historical<I> | undefined)[]>;

search<N extends CollectionName<C>, I extends { id: string }>(
collectionName: N,
options: PouchDB.Find.FindRequest<{}>
): Promise<Historical<I>[]>;

record<N extends CollectionName<C>, I extends { id: string }>(
collectionName: N,
inputs: (I | undefined)[],
options: { overwrite?: boolean }
): Promise<(Historical<I> | undefined)[]>;

forget<N extends CollectionName<C>, I extends { id: string }>(
collectionName: N,
references: (Pick<I, "id"> | undefined)[]
): Promise<void>;
}


/**
* Aggegrates logic for interacting wth a set of PouchDB databases identified
* by resource collection name.
Expand Down Expand Up @@ -303,161 +274,6 @@ export abstract class Databases<C extends Collections> implements Adapter<C> {
);
}

public async all<N extends CollectionName<C>>(
collectionName: N
): Promise<Historical<SavedInput<C, N>>[]> {
const log = debug.extend(`${collectionName}:all`);
log("Fetching all...");

try {
const result = await this.every<N, SavedInput<C, N>>(collectionName);

log("Found.");
return result;
} catch (error) {
log("Error fetching all %s, got error: %O", collectionName, error);
throw error;
}
}

public async find<N extends CollectionName<C>>(
collectionName: N,
options: (Id.IdObject<C, N> | undefined)[] | PouchDB.Find.FindRequest<{}>
): Promise<(Historical<SavedInput<C, N>> | undefined)[]> {
await this.ready;

const log = debug.extend(`${collectionName}:find`);
log("Finding...");

try {
// handle convenient interface for getting a bunch of IDs while preserving
// order of input request
if (Array.isArray(options)) {
const references = options;

return await this.retrieve<N, SavedInput<C, N>>(
collectionName,
references as (Pick<SavedInput<C, N>, "id"> | undefined)[]
);
}

const result = await this.search<N, SavedInput<C, N>>(
collectionName,
options
);

log("Found.");
return result;
} catch (error) {
log("Error fetching all %s, got error: %O", collectionName, error);
throw error;
}
}

public async get<N extends CollectionName<C>>(
collectionName: N,
id: string | undefined
): Promise<Historical<SavedInput<C, N>> | undefined> {
if (typeof id === "undefined") {
return;
}
const [savedInput] = await this.retrieve<N, SavedInput<C, N>>(
collectionName,
[{ id }]
);

return savedInput;
}

public async add<N extends CollectionName<C>>(
collectionName: N,
input: MutationInput<C, N>
): Promise<MutationPayload<C, N>> {
const log = debug.extend(`${collectionName}:add`);
log("Adding...");

const inputsWithIds = input[collectionName].map(
input => this.attachId(collectionName, input)
);

const addedInputs = await this.record<N, SavedInput<C, N>>(
collectionName,
inputsWithIds,
{ overwrite: false }
);

log(
"Added ids: %o",
addedInputs
.filter((input): input is Historical<SavedInput<C, N>> => !!input)
.map(({ id }) => id)
);

return {
[collectionName]: addedInputs
} as MutationPayload<C, N>;
}

public async update<M extends MutableCollectionName<C>>(
collectionName: M,
input: MutationInput<C, M>
): Promise<MutationPayload<C, M>> {
const log = debug.extend(`${collectionName}:update`);
log("Updating...");

const inputsWithIds = input[collectionName].map(
input => this.attachId(collectionName, input)
);

const updatedInputs = await this.record<M, SavedInput<C, M>>(
collectionName,
inputsWithIds,
{ overwrite: true }
);

log(
"Updated ids: %o",
updatedInputs
.filter((input): input is Historical<SavedInput<C, M>> => !!input)
.map(({ id }) => id)
);

return {
[collectionName]: updatedInputs
} as MutationPayload<C, M>;
}

public async remove<M extends MutableCollectionName<C>>(
collectionName: M,
input: MutationInput<C, M>
): Promise<void> {
const log = debug.extend(`${collectionName}:remove`);
log("Removing...");

const inputsWithIds = input[collectionName].map(
input => this.attachId(collectionName, input)
);

await this.forget(collectionName, inputsWithIds);

log("Removed.");
}

private attachId<N extends CollectionName<C>>(
collectionName: N,
input: Input<C, N> | undefined
) {
const id = this.generateId<N>(collectionName, input);

if (typeof id === "undefined") {
return;
}

return {
...input,
id
} as SavedInput<C, N>;
}
}

type CollectionDatabases<C extends Collections> = {
Expand Down
18 changes: 13 additions & 5 deletions packages/db/src/meta/pouch/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { logger } from "@truffle/db/logger";
const debug = logger("db:meta:pouch");

export { Definition, Definitions } from "./types";
import type { Collections } from "@truffle/db/meta/collections";
import type { Workspace } from "@truffle/db/meta/data";

import * as Adapters from "./adapters";
export { Adapters };

import type { Collections } from "@truffle/db/meta/collections";
import type { Workspace } from "@truffle/db/meta/data";
import type { Definitions } from "./types";
import { AdapterWorkspace } from "./workspace";

import type { Adapter, Definition, Definitions } from "./types";
export { Adapter, Definition, Definitions };


export const forDefinitions = <C extends Collections>(
definitions: Definitions<C>
Expand All @@ -19,7 +22,12 @@ export const forDefinitions = <C extends Collections>(

debug("Initializing workspace...");
// @ts-ignore
const workspace = new constructor({ definitions, settings });
const adapter: Adapter<C> = new constructor({ definitions, settings });

const workspace = new AdapterWorkspace<C>({
adapter,
definitions
});

return workspace;
};
28 changes: 28 additions & 0 deletions packages/db/src/meta/pouch/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,36 @@ const debug = logger("db:meta:pouch:types");
import PouchDB from "pouchdb";

import type { Collections, CollectionName } from "@truffle/db/meta/collections";
import type { Historical } from "@truffle/db/meta/data";
import type * as Id from "@truffle/db/meta/id";

export interface Adapter<C extends Collections> {
every<N extends CollectionName<C>, I extends { id: string }>(
collectionName: N
): Promise<Historical<I>[]>;

retrieve<N extends CollectionName<C>, I extends { id: string }>(
collectionName: N,
references: (Pick<I, "id"> | undefined)[]
): Promise<(Historical<I> | undefined)[]>;

search<N extends CollectionName<C>, I extends { id: string }>(
collectionName: N,
options: PouchDB.Find.FindRequest<{}>
): Promise<Historical<I>[]>;

record<N extends CollectionName<C>, I extends { id: string }>(
collectionName: N,
inputs: (I | undefined)[],
options: { overwrite?: boolean }
): Promise<(Historical<I> | undefined)[]>;

forget<N extends CollectionName<C>, I extends { id: string }>(
collectionName: N,
references: (Pick<I, "id"> | undefined)[]
): Promise<void>;
}

/**
* @category Definitions
*/
Expand Down
Loading

0 comments on commit efb7629

Please sign in to comment.