@vantreeseba/drizzle-graphql 10.0.1 → 10.0.3

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/dist/index.cjs CHANGED
@@ -1537,11 +1537,44 @@ const extractUniqueKeyFilter = (table, tableName, fieldName, members, value) =>
1537
1537
  };
1538
1538
  //#endregion
1539
1539
  //#region src/util/builders/common/relation-filters.ts
1540
- /** Narrows the build-scoped relation filter context to the table a resolver is filtering. */
1541
- const relationFilterCtx = (base, tableKey) => base ? {
1542
- ...base,
1543
- tableKey
1544
- } : void 0;
1540
+ /**
1541
+ * The narrowed contexts already handed out, keyed by the build-scoped base and then by
1542
+ * table. The base is created once per `buildSchema` and the result depends on nothing else,
1543
+ * so every call for one table produces the same value — a `WeakMap` on the base keeps them
1544
+ * for exactly as long as that build is reachable.
1545
+ */
1546
+ const narrowedCtxCache = /* @__PURE__ */ new WeakMap();
1547
+ /**
1548
+ * Narrows the build-scoped relation filter context to the table a resolver is filtering.
1549
+ *
1550
+ * Cached rather than rebuilt: the base carries the build's whole `tables` and `relationMap`,
1551
+ * and the spread copied both on every call — three per parent row in the lazy relation
1552
+ * resolver, one per parent row in the relation aggregate, and up to four per select, several
1553
+ * of them inside callbacks drizzle invokes lazily.
1554
+ *
1555
+ * The one field written after the fact is `aliases`, the counter that keeps subquery aliases
1556
+ * apart ({@link extractRelationFilter}). Sharing it is what makes the caching safe rather
1557
+ * than a hazard: the counter now spans the process instead of restarting per extraction, and
1558
+ * aliases only ever have to be unique *within* one statement, which a number that never
1559
+ * repeats gives more surely than one that restarts.
1560
+ */
1561
+ const relationFilterCtx = (base, tableKey) => {
1562
+ if (!base) return;
1563
+ let byTable = narrowedCtxCache.get(base);
1564
+ if (!byTable) {
1565
+ byTable = /* @__PURE__ */ new Map();
1566
+ narrowedCtxCache.set(base, byTable);
1567
+ }
1568
+ let ctx = byTable.get(tableKey);
1569
+ if (!ctx) {
1570
+ ctx = {
1571
+ ...base,
1572
+ tableKey
1573
+ };
1574
+ byTable.set(tableKey, ctx);
1575
+ }
1576
+ return ctx;
1577
+ };
1545
1578
  /**
1546
1579
  * Correlates the parent row with the aliased target table using the relation's own join
1547
1580
  * columns. Columns are matched by SQL name rather than object identity so this also works when
@@ -3145,16 +3178,23 @@ const extractRelationsParams = (relationMap, tables, tableName, info, typeName,
3145
3178
  if (!info) return;
3146
3179
  const relationsForTable = relationMap[tableName];
3147
3180
  if (!relationsForTable) return;
3148
- const baseField = Object.entries(info.fieldsByTypeName).find(([key, _value]) => key === typeName)?.[1];
3181
+ const baseField = info.fieldsByTypeName[typeName];
3149
3182
  if (!baseField) return;
3183
+ const selectionsByName = /* @__PURE__ */ new Map();
3184
+ for (const selection of Object.values(baseField)) {
3185
+ const selections = selectionsByName.get(selection.name);
3186
+ if (selections) selections.push(selection);
3187
+ else selectionsByName.set(selection.name, [selection]);
3188
+ }
3150
3189
  const args = {};
3151
3190
  for (const [relName, relEntry] of Object.entries(relationsForTable)) {
3152
3191
  const { targetTableName, targetPkNames } = relEntry;
3153
3192
  const relTypeName = resolveObjectTypeName(targetTableName, typeNameMapper, resolveName);
3154
- const field = baseField[relName] ?? Object.values(baseField).find((f) => f.name === relName);
3155
- if (!field) continue;
3156
- if (Object.values(baseField).reduce((n, f) => n + (f.name === relName ? 1 : 0), 0) > 1) continue;
3157
- const relFieldSelection = (field?.fieldsByTypeName)?.[relTypeName];
3193
+ const selections = selectionsByName.get(relName);
3194
+ if (!selections) continue;
3195
+ const field = selections[0];
3196
+ if (selections.length > 1) continue;
3197
+ const relFieldSelection = field.fieldsByTypeName[relTypeName];
3158
3198
  if (!relFieldSelection) continue;
3159
3199
  const eagerArgs = field.args;
3160
3200
  if (!(0, drizzle_orm.is)(relEntry.relation ?? relEntry, drizzle_orm.One) && (eagerArgs?.after != null || !!(eagerArgs?.distinct)?.length || isCursorFieldSelected(relFieldSelection, tables[targetTableName]))) continue;
@@ -3166,8 +3206,7 @@ const extractRelationsParams = (relationMap, tables, tableName, info, typeName,
3166
3206
  });
3167
3207
  const thisRecord = {};
3168
3208
  thisRecord.columns = columns;
3169
- const relationField = Object.values(baseField).find((e) => e.name === relName);
3170
- const relationArgs = (0, drizzle_orm.is)(relEntry.relation, drizzle_orm.One) ? relationField?.args : relationField && withDefaultOrderBy(relationField.args ?? {}, targetTableName, defaultOrderBy);
3209
+ const relationArgs = (0, drizzle_orm.is)(relEntry.relation, drizzle_orm.One) ? field.args : withDefaultOrderBy(field.args ?? {}, targetTableName, defaultOrderBy);
3171
3210
  const offset = relationArgs?.offset ?? void 0;
3172
3211
  const limit = (0, drizzle_orm.is)(relEntry.relation, drizzle_orm.One) ? relationArgs?.limit ?? void 0 : applyLimitPolicy(relationArgs?.limit, limits?.(targetTableName), {
3173
3212
  table: targetTableName,
@@ -3182,7 +3221,7 @@ const extractRelationsParams = (relationMap, tables, tableName, info, typeName,
3182
3221
  thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, relationArgs.orderBy, relationFilterCtx(filterCtx, targetTableName), relWhere) : hasPagination && pkNames.length ? (aliasedTable) => primaryKeyOrderExprs(aliasedTable, pkNames) : void 0;
3183
3222
  thisRecord.offset = offset;
3184
3223
  thisRecord.limit = limit;
3185
- thisRecord.with = extractRelationsParams(relationMap, tables, targetTableName, relationField, relTypeName, options);
3224
+ thisRecord.with = extractRelationsParams(relationMap, tables, targetTableName, field, relTypeName, options);
3186
3225
  args[relName] = thisRecord;
3187
3226
  }
3188
3227
  return args;