Skip to content

Commit

Permalink
Lookup individual nodes from anywhere.
Browse files Browse the repository at this point in the history
We need to be able to lookup a node from anywhere in a hierarchy so
that it can be loaded lazily.

This adds a `get()` method onto the return value of `factory.all()` to
find the node. It can also be used for implementing the Relay `node
{}` query.
  • Loading branch information
cowboyd committed Sep 8, 2022
1 parent 5ca9bb5 commit 3b6c71d
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
16 changes: 14 additions & 2 deletions src/graphql/graphgen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,17 @@ export interface GraphGen<API = Record<string, any>> {
typename: T,
preset?: Preset<API[T]>,
): Node & API[T];
all<T extends string & keyof API>(typename: T): Iterable<Node & API[T]>;
all<T extends string & keyof API>(typename: T): Collection<Node & API[T]>;
createMany<T extends string & keyof API>(
typename: T,
amount: number,
): Iterable<Node & API[T]>;
}

export interface Collection<T> extends Iterable<T> {
get(id: string): T | undefined;
}

export interface Generate {
(info: GenerateInfo): unknown;
}
Expand Down Expand Up @@ -274,13 +278,21 @@ directive @computed on FIELD_DEFINITION
return transformed;
}

function all<T extends string & keyof API>(typename: T) {
function all<T extends string & keyof API>(
typename: T,
): Collection<Node & API[T]> {
return {
*[Symbol.iterator]() {
for (let id in graph.roots[typename]) {
yield toNode<API[typeof typename]>(graph.roots[typename][id]);
}
},
get(id) {
let vertex = graph.roots[typename][Number(id)];
if (vertex) {
return toNode(vertex);
}
},
};
}

Expand Down
5 changes: 5 additions & 0 deletions test/graphql.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ describe("using graphql", () => {
expect(all).toHaveLength(3);
});

it("can lookup a single node by type and id", () => {
let person = graphgen.create("Person");
expect(graphgen.all("Person").get(person.id)).toBe(person);
});

it("assigns an id and corresponding typename to each node", () => {
let person = graphgen.create("Person");
expect(person.id).toBe("1");
Expand Down

0 comments on commit 3b6c71d

Please sign in to comment.