@m1212e/rumble 0.23.13 → 0.23.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/out/index.mjs CHANGED
@@ -18,6 +18,7 @@ import DrizzlePlugin from "@pothos/plugin-drizzle";
18
18
  import SmartSubscriptionsPlugin, { subscribeOptionsFromIterator } from "@pothos/plugin-smart-subscriptions";
19
19
  import TracingPlugin, { isRootField, wrapResolver } from "@pothos/plugin-tracing";
20
20
  import { BigIntResolver, ByteResolver, DateResolver, DateTimeISOResolver, JSONResolver } from "graphql-scalars";
21
+ import DataLoader from "dataloader";
21
22
  //#region lib/types/rumbleError.ts
22
23
  /**
23
24
  * An error that gets raised by rumble whenever something does not go according to plan.
@@ -180,7 +181,7 @@ function mapNullFieldsToUndefined(obj) {
180
181
  }
181
182
  //#endregion
182
183
  //#region package.json
183
- var version = "0.23.13";
184
+ var version = "0.23.15";
184
185
  //#endregion
185
186
  //#region lib/helpers/mergeFilters.ts
186
187
  const EmptyFilter$1 = Symbol.for("drizzle:EmptyFilter");
@@ -219,7 +220,7 @@ function isPlainObject(value) {
219
220
  return proto === Object.prototype || proto === null;
220
221
  }
221
222
  function sanitizeFilterValue(value) {
222
- if (value === void 0) return EmptyFilter;
223
+ if (value === void 0 || value === null) return EmptyFilter;
223
224
  if (Array.isArray(value)) return value.map(sanitizeFilterValue);
224
225
  if (isPlainObject(value)) return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, sanitizeFilterValue(entry)]));
225
226
  return value;
@@ -2281,6 +2282,30 @@ var RuntimeFiltersPlugin = class extends BasePlugin {
2281
2282
  tracer;
2282
2283
  tracerEnabled;
2283
2284
  logger;
2285
+ filterLoaders = /* @__PURE__ */ new WeakMap();
2286
+ getLoader(context, filter) {
2287
+ let perContext = this.filterLoaders.get(context);
2288
+ if (!perContext) {
2289
+ perContext = /* @__PURE__ */ new Map();
2290
+ this.filterLoaders.set(context, perContext);
2291
+ }
2292
+ let loader = perContext.get(filter);
2293
+ if (!loader) {
2294
+ const prefetchPromise = filter.prefetch ? filter.prefetch({ context }) : void 0;
2295
+ loader = new DataLoader(async (entities) => {
2296
+ const prefetched = prefetchPromise ? await prefetchPromise : void 0;
2297
+ const allowed = await filter.filter({
2298
+ context,
2299
+ entities,
2300
+ prefetched
2301
+ });
2302
+ const allowedSet = new Set(allowed);
2303
+ return entities.map((entity) => allowedSet.has(entity) ? entity : null);
2304
+ }, { cache: false });
2305
+ perContext.set(filter, loader);
2306
+ }
2307
+ return loader;
2308
+ }
2284
2309
  onTypeConfig(typeConfig) {
2285
2310
  this.tracer = this.builder.options.otel?.tracer;
2286
2311
  this.tracerEnabled = this.builder.options.otel?.enabled;
@@ -2297,44 +2322,20 @@ var RuntimeFiltersPlugin = class extends BasePlugin {
2297
2322
  const runFilters = async (span) => {
2298
2323
  const allFilters = Array.isArray(filters) ? filters : [filters];
2299
2324
  span?.setAttribute("filters.total", allFilters.length);
2300
- const prefetchedFiltersPromises = Promise.all(allFilters.map(async (filter) => {
2301
- if (filter.prefetch) {
2302
- const prefetched = await filter.prefetch({ context });
2303
- return ({ context, entities }) => filter.filter({
2304
- context,
2305
- entities,
2306
- prefetched
2307
- });
2325
+ const loaders = allFilters.map((filter) => this.getLoader(context, filter));
2326
+ let resolved;
2327
+ if (this.tracer && this.tracerEnabled) resolved = await this.tracer.startActiveSpan(`rumble.filter.resolve`, async (span) => {
2328
+ span.setAttribute("graphql.field.name", fieldConfig.name);
2329
+ try {
2330
+ return await resolver(parent, args, context, info);
2331
+ } finally {
2332
+ span.end();
2308
2333
  }
2309
- return ({ context, entities }) => filter.filter({
2310
- context,
2311
- entities
2312
- });
2313
- }));
2314
- let resolved, prefetchedFilters;
2315
- if (this.tracer && this.tracerEnabled) {
2316
- const o = await this.tracer.startActiveSpan(`rumble.filter.resolve`, async (span) => {
2317
- span.setAttribute("graphql.field.name", fieldConfig.name);
2318
- try {
2319
- return await Promise.all([resolver(parent, args, context, info), prefetchedFiltersPromises]);
2320
- } finally {
2321
- span.end();
2322
- }
2323
- });
2324
- resolved = o[0];
2325
- prefetchedFilters = o[1];
2326
- } else {
2327
- const o = await Promise.all([resolver(parent, args, context, info), prefetchedFiltersPromises]);
2328
- resolved = o[0];
2329
- prefetchedFilters = o[1];
2330
- }
2331
- const allowed = Array.from((await Promise.all(prefetchedFilters.map((f) => f({
2332
- context,
2333
- entities: Array.isArray(resolved) ? resolved : [resolved]
2334
- })))).reduce((acc, val) => {
2335
- for (const element of val) acc.add(element);
2336
- return acc;
2337
- }, /* @__PURE__ */ new Set()));
2334
+ });
2335
+ else resolved = await resolver(parent, args, context, info);
2336
+ const entities = Array.isArray(resolved) ? resolved : [resolved];
2337
+ const perFilterResults = await Promise.all(loaders.map((loader) => Promise.all(entities.map((entity) => loader.load(entity)))));
2338
+ const allowed = entities.filter((_, index) => perFilterResults.some((results) => results[index] != null));
2338
2339
  span?.setAttribute("filters.allowed", allowed.length);
2339
2340
  this.logger?.debug({
2340
2341
  "graphql.field.name": fieldConfig.name,