backend/lib/seed/services/database/LoaderService.ts
2025-05-14 21:45:16 +02:00

60 lines
2.4 KiB
TypeScript

/* eslint-disable @typescript-eslint/explicit-function-return-type */
import _ from 'lodash';
import DL from 'dataloader';
import { EngineModel } from '@seed/engine/EngineModel';
export class DataLoader<K, V, C = K> extends DL<K, V, C> {
async loadMany(keys: ArrayLike<K>): Promise<Array<V>> {
const nkeys = _.without(keys, undefined, null) as any;
const res = await super.loadMany(nkeys);
return _.without(res, undefined, null) as any;
}
}
/* V1 - Graph Model */
export const batchFunction = async <T>(model: T, _ids: any, field: string) => {
const results = await (await (model as any).db()).find({ [`${field}`]: { $in: _ids } }).toArray();
return _ids.map((_id) => results.find((result) => result[field] === _id));
};
export const batchOneToManyFunction = async <T>(model: T, _ids: any, field: string) => {
const results = await (await (model as any).db()).find({ [`${field}`]: { $in: _ids } }).toArray();
return _ids.map((_id) => _.filter(results, { [`${field}`]: _id }));
};
export const batchOneToManyFilterFunction = async <T>(model: T, _ids: any, field: string, filter: any) => {
const results = await (await (model as any).db()).find({ [`${field}`]: { $in: _ids }, ...filter }).toArray();
return _ids.map((_id) => _.filter(results, { [`${field}`]: _id }));
};
export const buildLoader = <T, V = T>(model: T, field = '_id') => {
return new DataLoader<string, V>((keys) => {
return batchFunction(model, keys, field);
});
};
export const buildOneToManyLoader = <T, V = T>(model: T, field = '_id') => {
return new DataLoader<string, Array<V>>((keys) => {
return batchOneToManyFunction(model, keys, field);
});
};
export const buildOneToManyFilterLoader = <T, V = T>(model: T, field = '_id', filter: any) => {
return new DataLoader<string, Array<V>>((keys) => {
return batchOneToManyFilterFunction(model, keys, field, filter);
});
};
/* V2 - Engine Model */
export const batchEngineFunction = async <T extends EngineModel<any, any, any>>(model: T, _ids: any, field: string) => {
const results = await model.getAll({ query: { [`${field}`]: { $in: _ids } } });
return _ids.map((_id) => results.find((result) => result[field] === _id));
};
export const buildEngineLoader = <T extends EngineModel<any, any, any>, V = T>(model: T, field = '_id') => {
return new DataLoader<string, V>((keys) => {
return batchEngineFunction(model, keys, field);
});
};