Skip to content

Commit

Permalink
[dataloader] expose info when using byPath
Browse files Browse the repository at this point in the history
  • Loading branch information
hayes committed Nov 7, 2024
1 parent 4458170 commit 10e364c
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/cyan-trainers-retire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@pothos/plugin-dataloader": minor
---

expose info when using byPath
8 changes: 4 additions & 4 deletions packages/plugin-dataloader/src/field-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fieldBuilderProto.loadable = function loadable<
InputShapeFromFields<Args>
>(
loaderOptions,
(keys, ctx, args) => load(keys, ctx, args as never),
(keys, ctx, args, info) => load(keys, ctx, args as never, info as never),
undefined,
sort as (value: LoaderShapeFromType<SchemaTypes, Type, Nullable>) => Key,
byPath,
Expand Down Expand Up @@ -124,7 +124,7 @@ fieldBuilderProto.loadableList = function loadableList<
InputShapeFromFields<Args>
>(
loaderOptions,
(keys, ctx, args) => load(keys, ctx, args as never),
(keys, ctx, args, info) => load(keys, ctx, args as never, info as never),
undefined,
sort as (value: ShapeFromTypeParam<SchemaTypes, [Type], Nullable>) => Key,
byPath,
Expand Down Expand Up @@ -183,8 +183,8 @@ fieldBuilderProto.loadableGroup = function loadableGroup<
InputShapeFromFields<Args>
>(
loaderOptions,
async (keys, ctx, args) => {
const values = await load(keys, ctx, args as never);
async (keys, ctx, args, info) => {
const values = await load(keys, ctx, args as never, info as never);
const groups = new Map<Key, ShapeFromTypeParam<SchemaTypes, Type, true>[]>();

for (const value of values) {
Expand Down
4 changes: 4 additions & 0 deletions packages/plugin-dataloader/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import type {
TypeParam,
} from '@pothos/core';
import type DataLoader from 'dataloader';
import type { GraphQLResolveInfo } from 'graphql';

export type DataloaderKey = bigint | number | string;

Expand All @@ -44,6 +45,7 @@ export type LoadableFieldOptions<
keys: Key[],
context: Types['Context'],
args: false extends ByPath ? never : InputShapeFromFields<Args>,
info: false extends ByPath ? never : GraphQLResolveInfo,
) => Promise<readonly (Error | LoaderShapeFromType<Types, Type, Nullable>)[]>;
loaderOptions?: DataLoader.Options<Key, LoaderShapeFromType<Types, Type, Nullable>, CacheKey>;
sort?: (value: LoaderShapeFromType<Types, Type, false>) => Key;
Expand Down Expand Up @@ -85,6 +87,7 @@ export type LoadableListFieldOptions<
keys: Key[],
context: Types['Context'],
args: false extends ByPath ? never : InputShapeFromFields<Args>,
info: false extends ByPath ? never : GraphQLResolveInfo,
) => Promise<readonly (Error | ShapeFromTypeParam<Types, [Type], Nullable>)[]>;
loaderOptions?: DataLoader.Options<Key, ShapeFromTypeParam<Types, [Type], Nullable>, CacheKey>;
sort?: (value: ShapeFromTypeParam<Types, [Type], false>) => Key;
Expand Down Expand Up @@ -118,6 +121,7 @@ export type LoadableGroupFieldOptions<
keys: Key[],
context: Types['Context'],
args: false extends ByPath ? never : InputShapeFromFields<Args>,
info: false extends ByPath ? never : GraphQLResolveInfo,
) => Promise<readonly ShapeFromTypeParam<Types, Type, true>[]>;
loaderOptions?: DataLoader.Options<Key, ShapeFromTypeParam<Types, Type, true>[], CacheKey>;
group: (value: ShapeFromTypeParam<Types, Type, false>) => Key;
Expand Down
16 changes: 11 additions & 5 deletions packages/plugin-dataloader/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ export function rejectErrors<T>(
}

export function loadAndSort<K, V, C, LoadResult, Args = never>(
load: (keys: K[], context: C, args: Args) => MaybePromise<LoadResult>,
load: (keys: K[], context: C, args: Args, info: GraphQLResolveInfo) => MaybePromise<LoadResult>,
toKey: false | ((val: V) => K) | undefined,
) {
if (!toKey) {
return load;
}

return async (keys: K[], context: C, args: Args) => {
const list = await load(keys, context, args);
return async (keys: K[], context: C, args: Args, info: GraphQLResolveInfo) => {
const list = await load(keys, context, args, info);
const map = new Map<K, V>();
const results = new Array<V | null>();

Expand Down Expand Up @@ -61,7 +61,12 @@ export function dataloaderGetter<K, V, C>(

export function pathDataloaderGetter<K, V, C, Args>(
loaderOptions: Options<K, V, C> | undefined,
load: (keys: K[], context: SchemaTypes['Context'], args: Args) => Promise<readonly (Error | V)[]>,
load: (
keys: K[],
context: SchemaTypes['Context'],
args: Args,
info: GraphQLResolveInfo,
) => Promise<readonly (Error | V)[]>,
toKey: ((val: V) => K) | undefined,
sort: boolean | ((val: V) => K) | undefined,
byPath?: boolean,
Expand All @@ -72,14 +77,15 @@ export function pathDataloaderGetter<K, V, C, Args>(
keys: readonly K[],
context: SchemaTypes['Context'],
args: Args,
info: GraphQLResolveInfo,
) => Promise<V[]>;

return (args: Args, ctx: SchemaTypes['Context'], info: GraphQLResolveInfo) => {
const key = byPath ? cacheKey(info.path) : '*';
const map = cache(ctx);

if (!map.has(key)) {
map.set(key, new DataLoader<K, V, C>((keys) => loader(keys, ctx, args), loaderOptions));
map.set(key, new DataLoader<K, V, C>((keys) => loader(keys, ctx, args, info), loaderOptions));
}

return map.get(key)!;
Expand Down

0 comments on commit 10e364c

Please sign in to comment.