@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.js CHANGED
@@ -1513,11 +1513,44 @@ const extractUniqueKeyFilter = (table, tableName, fieldName, members, value) =>
1513
1513
  };
1514
1514
  //#endregion
1515
1515
  //#region src/util/builders/common/relation-filters.ts
1516
- /** Narrows the build-scoped relation filter context to the table a resolver is filtering. */
1517
- const relationFilterCtx = (base, tableKey) => base ? {
1518
- ...base,
1519
- tableKey
1520
- } : void 0;
1516
+ /**
1517
+ * The narrowed contexts already handed out, keyed by the build-scoped base and then by
1518
+ * table. The base is created once per `buildSchema` and the result depends on nothing else,
1519
+ * so every call for one table produces the same value — a `WeakMap` on the base keeps them
1520
+ * for exactly as long as that build is reachable.
1521
+ */
1522
+ const narrowedCtxCache = /* @__PURE__ */ new WeakMap();
1523
+ /**
1524
+ * Narrows the build-scoped relation filter context to the table a resolver is filtering.
1525
+ *
1526
+ * Cached rather than rebuilt: the base carries the build's whole `tables` and `relationMap`,
1527
+ * and the spread copied both on every call — three per parent row in the lazy relation
1528
+ * resolver, one per parent row in the relation aggregate, and up to four per select, several
1529
+ * of them inside callbacks drizzle invokes lazily.
1530
+ *
1531
+ * The one field written after the fact is `aliases`, the counter that keeps subquery aliases
1532
+ * apart ({@link extractRelationFilter}). Sharing it is what makes the caching safe rather
1533
+ * than a hazard: the counter now spans the process instead of restarting per extraction, and
1534
+ * aliases only ever have to be unique *within* one statement, which a number that never
1535
+ * repeats gives more surely than one that restarts.
1536
+ */
1537
+ const relationFilterCtx = (base, tableKey) => {
1538
+ if (!base) return;
1539
+ let byTable = narrowedCtxCache.get(base);
1540
+ if (!byTable) {
1541
+ byTable = /* @__PURE__ */ new Map();
1542
+ narrowedCtxCache.set(base, byTable);
1543
+ }
1544
+ let ctx = byTable.get(tableKey);
1545
+ if (!ctx) {
1546
+ ctx = {
1547
+ ...base,
1548
+ tableKey
1549
+ };
1550
+ byTable.set(tableKey, ctx);
1551
+ }
1552
+ return ctx;
1553
+ };
1521
1554
  /**
1522
1555
  * Correlates the parent row with the aliased target table using the relation's own join
1523
1556
  * columns. Columns are matched by SQL name rather than object identity so this also works when
@@ -3121,16 +3154,23 @@ const extractRelationsParams = (relationMap, tables, tableName, info, typeName,
3121
3154
  if (!info) return;
3122
3155
  const relationsForTable = relationMap[tableName];
3123
3156
  if (!relationsForTable) return;
3124
- const baseField = Object.entries(info.fieldsByTypeName).find(([key, _value]) => key === typeName)?.[1];
3157
+ const baseField = info.fieldsByTypeName[typeName];
3125
3158
  if (!baseField) return;
3159
+ const selectionsByName = /* @__PURE__ */ new Map();
3160
+ for (const selection of Object.values(baseField)) {
3161
+ const selections = selectionsByName.get(selection.name);
3162
+ if (selections) selections.push(selection);
3163
+ else selectionsByName.set(selection.name, [selection]);
3164
+ }
3126
3165
  const args = {};
3127
3166
  for (const [relName, relEntry] of Object.entries(relationsForTable)) {
3128
3167
  const { targetTableName, targetPkNames } = relEntry;
3129
3168
  const relTypeName = resolveObjectTypeName(targetTableName, typeNameMapper, resolveName);
3130
- const field = baseField[relName] ?? Object.values(baseField).find((f) => f.name === relName);
3131
- if (!field) continue;
3132
- if (Object.values(baseField).reduce((n, f) => n + (f.name === relName ? 1 : 0), 0) > 1) continue;
3133
- const relFieldSelection = (field?.fieldsByTypeName)?.[relTypeName];
3169
+ const selections = selectionsByName.get(relName);
3170
+ if (!selections) continue;
3171
+ const field = selections[0];
3172
+ if (selections.length > 1) continue;
3173
+ const relFieldSelection = field.fieldsByTypeName[relTypeName];
3134
3174
  if (!relFieldSelection) continue;
3135
3175
  const eagerArgs = field.args;
3136
3176
  if (!is(relEntry.relation ?? relEntry, One) && (eagerArgs?.after != null || !!(eagerArgs?.distinct)?.length || isCursorFieldSelected(relFieldSelection, tables[targetTableName]))) continue;
@@ -3142,8 +3182,7 @@ const extractRelationsParams = (relationMap, tables, tableName, info, typeName,
3142
3182
  });
3143
3183
  const thisRecord = {};
3144
3184
  thisRecord.columns = columns;
3145
- const relationField = Object.values(baseField).find((e) => e.name === relName);
3146
- const relationArgs = is(relEntry.relation, One) ? relationField?.args : relationField && withDefaultOrderBy(relationField.args ?? {}, targetTableName, defaultOrderBy);
3185
+ const relationArgs = is(relEntry.relation, One) ? field.args : withDefaultOrderBy(field.args ?? {}, targetTableName, defaultOrderBy);
3147
3186
  const offset = relationArgs?.offset ?? void 0;
3148
3187
  const limit = is(relEntry.relation, One) ? relationArgs?.limit ?? void 0 : applyLimitPolicy(relationArgs?.limit, limits?.(targetTableName), {
3149
3188
  table: targetTableName,
@@ -3158,7 +3197,7 @@ const extractRelationsParams = (relationMap, tables, tableName, info, typeName,
3158
3197
  thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, relationArgs.orderBy, relationFilterCtx(filterCtx, targetTableName), relWhere) : hasPagination && pkNames.length ? (aliasedTable) => primaryKeyOrderExprs(aliasedTable, pkNames) : void 0;
3159
3198
  thisRecord.offset = offset;
3160
3199
  thisRecord.limit = limit;
3161
- thisRecord.with = extractRelationsParams(relationMap, tables, targetTableName, relationField, relTypeName, options);
3200
+ thisRecord.with = extractRelationsParams(relationMap, tables, targetTableName, field, relTypeName, options);
3162
3201
  args[relName] = thisRecord;
3163
3202
  }
3164
3203
  return args;