Feature Request: Hook/callback for internal findMany calls
Problem
When using prisma-extension-pagination alongside extensions that add custom args to queries (e.g. prisma-extension-redis's cache option), there's no way to differentiate between the multiple internal findMany calls the pagination library makes.
For cursor-based pagination, paginateWithCursor runs 2 concurrent findMany calls via Promise.all:
- The main results query (
take: limit + 1)
- A boundary check query (
take: -1 or take: 1)
Since both calls receive the same spread of ...query, any custom args (like a cache key) are identical for both. This causes issues like cache key collisions where the boundary check overwrites the main results in cache.
Current workaround
We currently have to strip custom args in paginate() and use a Proxy around the model to re-inject them with a unique suffix per internal findMany call. This works but adds complexity that shouldn't be necessary.
Proposed solution
Expose a onFindMany (or wrapFindMany) callback that receives the args for each internal findMany call along with context about which call it is:
const [users, meta] = await prisma.user
.paginate({
where: { status: 'active' },
orderBy: { id: 'asc' },
})
.withCursor({
limit: 10,
after: cursor,
onFindMany: (args, context) => {
// context.type: 'results' | 'boundaryCheck' | 'count'
// context.index: 0, 1, 2...
return {
...args,
cache: {
key: `my:cache:key:${context.type}`,
},
};
},
});
Alternative: strip unknown args
A simpler (but less flexible) approach would be to strip any non-Prisma args before passing them into internal findMany calls, and instead accept extension-specific config as a separate top-level option:
.paginate({
where: { status: 'active' },
}, {
// Separate bag for extension args, not spread into findMany
extensions: { cache: { key: 'my:key' } }
})
Context
This is specifically painful when combining with prisma-extension-redis, but would affect any Prisma extension that adds custom args to findMany. Related discussion: the pagination library currently spreads the full query object into every internal call without filtering, which leaks consumer-provided custom args into calls they weren't intended for.
Feature Request: Hook/callback for internal
findManycallsProblem
When using
prisma-extension-paginationalongside extensions that add custom args to queries (e.g.prisma-extension-redis'scacheoption), there's no way to differentiate between the multiple internalfindManycalls the pagination library makes.For cursor-based pagination,
paginateWithCursorruns 2 concurrentfindManycalls viaPromise.all:take: limit + 1)take: -1ortake: 1)Since both calls receive the same spread of
...query, any custom args (like acachekey) are identical for both. This causes issues like cache key collisions where the boundary check overwrites the main results in cache.Current workaround
We currently have to strip custom args in
paginate()and use aProxyaround the model to re-inject them with a unique suffix per internalfindManycall. This works but adds complexity that shouldn't be necessary.Proposed solution
Expose a
onFindMany(orwrapFindMany) callback that receives the args for each internalfindManycall along with context about which call it is:Alternative: strip unknown args
A simpler (but less flexible) approach would be to strip any non-Prisma args before passing them into internal
findManycalls, and instead accept extension-specific config as a separate top-level option:Context
This is specifically painful when combining with
prisma-extension-redis, but would affect any Prisma extension that adds custom args tofindMany. Related discussion: the pagination library currently spreads the full query object into every internal call without filtering, which leaks consumer-provided custom args into calls they weren't intended for.