@remix-run/data-table 0.5.0 → 0.5.1

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.
@@ -62,10 +62,11 @@ async function loadHasManyThroughValues(database, sourceRows, relation) {
62
62
  if (!relation.through) {
63
63
  throw new DataTableQueryError('hasManyThrough relation is missing through metadata');
64
64
  }
65
+ let through = relation.through;
65
66
  if (sourceRows.length === 0) {
66
67
  return [];
67
68
  }
68
- let throughRelation = relation.through.relation;
69
+ let throughRelation = through.relation;
69
70
  let sourceTuples = uniqueTuples(sourceRows, throughRelation.sourceKey);
70
71
  if (sourceTuples.length === 0) {
71
72
  return sourceRows.map(() => []);
@@ -92,12 +93,12 @@ async function loadHasManyThroughValues(database, sourceRows, relation) {
92
93
  pagedThroughRowsBySource.set(sourceKey, pagedMatchedRows);
93
94
  pagedThroughRows.push(...pagedMatchedRows);
94
95
  }
95
- let throughTuples = uniqueTuples(pagedThroughRows, relation.through.throughSourceKey);
96
+ let throughTuples = uniqueTuples(pagedThroughRows, through.throughSourceKey);
96
97
  if (throughTuples.length === 0) {
97
98
  return sourceRows.map(() => []);
98
99
  }
99
100
  let targetQuery = createQuery(relation.targetTable);
100
- let targetPredicate = buildLinkPredicate(relation.through.throughTargetKey, throughTuples);
101
+ let targetPredicate = buildLinkPredicate(through.throughTargetKey, throughTuples);
101
102
  if (targetPredicate) {
102
103
  targetQuery = targetQuery.where(targetPredicate);
103
104
  }
@@ -105,23 +106,41 @@ async function loadHasManyThroughValues(database, sourceRows, relation) {
105
106
  includePagination: false,
106
107
  });
107
108
  let relatedRows = await loadRowsWithRelationsForQuery(database, targetQuery);
108
- let targetRowsByThrough = groupRowsByTuple(relatedRows, relation.through.throughTargetKey);
109
- return sourceRows.map((sourceRow) => {
109
+ let sourceKeysByThroughKey = new Map();
110
+ let outputRowsBySourceKey = new Map();
111
+ for (let sourceRow of sourceRows) {
110
112
  let sourceKey = getCompositeKey(sourceRow, throughRelation.sourceKey);
111
113
  let matchedThroughRows = pagedThroughRowsBySource.get(sourceKey) ?? [];
112
- let outputRows = [];
113
- let seen = new Set();
114
+ outputRowsBySourceKey.set(sourceKey, new Map());
114
115
  for (let throughRow of matchedThroughRows) {
115
- let throughKey = getCompositeKey(throughRow, relation.through.throughSourceKey);
116
- let rowsForThrough = targetRowsByThrough.get(throughKey) ?? [];
117
- for (let row of rowsForThrough) {
118
- let rowIdentity = getCompositeKey(row, getTablePrimaryKey(relation.targetTable));
119
- if (!seen.has(rowIdentity)) {
120
- seen.add(rowIdentity);
121
- outputRows.push(row);
122
- }
116
+ let throughKey = getCompositeKey(throughRow, through.throughSourceKey);
117
+ let sourceKeys = sourceKeysByThroughKey.get(throughKey);
118
+ if (!sourceKeys) {
119
+ sourceKeys = new Set();
120
+ sourceKeysByThroughKey.set(throughKey, sourceKeys);
121
+ }
122
+ sourceKeys.add(sourceKey);
123
+ }
124
+ }
125
+ let targetPrimaryKey = getTablePrimaryKey(relation.targetTable);
126
+ for (let row of relatedRows) {
127
+ let throughKey = getCompositeKey(row, through.throughTargetKey);
128
+ let sourceKeys = sourceKeysByThroughKey.get(throughKey);
129
+ if (!sourceKeys) {
130
+ continue;
131
+ }
132
+ let rowIdentity = getCompositeKey(row, targetPrimaryKey);
133
+ for (let sourceKey of sourceKeys) {
134
+ let outputRows = outputRowsBySourceKey.get(sourceKey);
135
+ if (!outputRows || outputRows.has(rowIdentity)) {
136
+ continue;
123
137
  }
138
+ outputRows.set(rowIdentity, row);
124
139
  }
140
+ }
141
+ return sourceRows.map((sourceRow) => {
142
+ let sourceKey = getCompositeKey(sourceRow, throughRelation.sourceKey);
143
+ let outputRows = Array.from(outputRowsBySourceKey.get(sourceKey)?.values() ?? []);
125
144
  return applyPagination(outputRows, relation.modifiers.limit, relation.modifiers.offset);
126
145
  });
127
146
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remix-run/data-table",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "A typed, relational query toolkit for JavaScript",
5
5
  "author": "Michael Jackson <mjijackson@gmail.com>",
6
6
  "license": "MIT",
@@ -49,8 +49,8 @@
49
49
  "devDependencies": {
50
50
  "@types/node": "^24.6.0",
51
51
  "typescript": "^7.0.2",
52
- "@remix-run/test": "0.6.0",
53
- "@remix-run/assert": "0.3.0"
52
+ "@remix-run/assert": "0.3.0",
53
+ "@remix-run/test": "0.6.0"
54
54
  },
55
55
  "dependencies": {},
56
56
  "keywords": [
@@ -116,11 +116,13 @@ async function loadHasManyThroughValues(
116
116
  throw new DataTableQueryError('hasManyThrough relation is missing through metadata')
117
117
  }
118
118
 
119
+ let through = relation.through
120
+
119
121
  if (sourceRows.length === 0) {
120
122
  return []
121
123
  }
122
124
 
123
- let throughRelation = relation.through.relation
125
+ let throughRelation = through.relation
124
126
  let sourceTuples = uniqueTuples(sourceRows, throughRelation.sourceKey)
125
127
 
126
128
  if (sourceTuples.length === 0) {
@@ -163,14 +165,14 @@ async function loadHasManyThroughValues(
163
165
  pagedThroughRows.push(...pagedMatchedRows)
164
166
  }
165
167
 
166
- let throughTuples = uniqueTuples(pagedThroughRows, relation.through.throughSourceKey)
168
+ let throughTuples = uniqueTuples(pagedThroughRows, through.throughSourceKey)
167
169
 
168
170
  if (throughTuples.length === 0) {
169
171
  return sourceRows.map(() => [])
170
172
  }
171
173
 
172
174
  let targetQuery = createQuery(relation.targetTable)
173
- let targetPredicate = buildLinkPredicate(relation.through.throughTargetKey, throughTuples)
175
+ let targetPredicate = buildLinkPredicate(through.throughTargetKey, throughTuples)
174
176
 
175
177
  if (targetPredicate) {
176
178
  targetQuery = targetQuery.where(
@@ -183,27 +185,54 @@ async function loadHasManyThroughValues(
183
185
  })
184
186
 
185
187
  let relatedRows = await loadRowsWithRelationsForQuery(database, targetQuery)
186
- let targetRowsByThrough = groupRowsByTuple(relatedRows, relation.through.throughTargetKey)
188
+ let sourceKeysByThroughKey = new Map<string, Set<string>>()
189
+ let outputRowsBySourceKey = new Map<string, Map<string, Record<string, unknown>>>()
187
190
 
188
- return sourceRows.map((sourceRow) => {
191
+ for (let sourceRow of sourceRows) {
189
192
  let sourceKey = getCompositeKey(sourceRow, throughRelation.sourceKey)
190
193
  let matchedThroughRows = pagedThroughRowsBySource.get(sourceKey) ?? []
191
- let outputRows: Record<string, unknown>[] = []
192
- let seen = new Set<string>()
194
+
195
+ outputRowsBySourceKey.set(sourceKey, new Map())
193
196
 
194
197
  for (let throughRow of matchedThroughRows) {
195
- let throughKey = getCompositeKey(throughRow, relation.through!.throughSourceKey)
196
- let rowsForThrough = targetRowsByThrough.get(throughKey) ?? []
198
+ let throughKey = getCompositeKey(throughRow, through.throughSourceKey)
199
+ let sourceKeys = sourceKeysByThroughKey.get(throughKey)
200
+
201
+ if (!sourceKeys) {
202
+ sourceKeys = new Set()
203
+ sourceKeysByThroughKey.set(throughKey, sourceKeys)
204
+ }
205
+
206
+ sourceKeys.add(sourceKey)
207
+ }
208
+ }
209
+
210
+ let targetPrimaryKey = getTablePrimaryKey(relation.targetTable)
197
211
 
198
- for (let row of rowsForThrough) {
199
- let rowIdentity = getCompositeKey(row, getTablePrimaryKey(relation.targetTable))
212
+ for (let row of relatedRows) {
213
+ let throughKey = getCompositeKey(row, through.throughTargetKey)
214
+ let sourceKeys = sourceKeysByThroughKey.get(throughKey)
200
215
 
201
- if (!seen.has(rowIdentity)) {
202
- seen.add(rowIdentity)
203
- outputRows.push(row)
204
- }
216
+ if (!sourceKeys) {
217
+ continue
218
+ }
219
+
220
+ let rowIdentity = getCompositeKey(row, targetPrimaryKey)
221
+
222
+ for (let sourceKey of sourceKeys) {
223
+ let outputRows = outputRowsBySourceKey.get(sourceKey)
224
+
225
+ if (!outputRows || outputRows.has(rowIdentity)) {
226
+ continue
205
227
  }
228
+
229
+ outputRows.set(rowIdentity, row)
206
230
  }
231
+ }
232
+
233
+ return sourceRows.map((sourceRow) => {
234
+ let sourceKey = getCompositeKey(sourceRow, throughRelation.sourceKey)
235
+ let outputRows = Array.from(outputRowsBySourceKey.get(sourceKey)?.values() ?? [])
207
236
 
208
237
  return applyPagination(outputRows, relation.modifiers.limit, relation.modifiers.offset)
209
238
  })