houdini 0.17.13 → 0.18.0
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/build/cmd-cjs/index.js +438 -201
- package/build/cmd-esm/index.js +438 -201
- package/build/codegen/utils/flattenSelections.d.ts +3 -1
- package/build/codegen-cjs/index.js +405 -180
- package/build/codegen-esm/index.js +405 -180
- package/build/lib/config.d.ts +8 -3
- package/build/lib-cjs/index.js +141 -81
- package/build/lib-esm/index.js +141 -81
- package/build/runtime/cache/subscription.d.ts +3 -3
- package/build/runtime/lib/config.d.ts +2 -1
- package/build/runtime/lib/scalars.d.ts +2 -2
- package/build/runtime/lib/selection.d.ts +2 -0
- package/build/runtime/lib/types.d.ts +26 -16
- package/build/runtime-cjs/cache/cache.js +38 -23
- package/build/runtime-cjs/cache/lists.js +40 -26
- package/build/runtime-cjs/cache/subscription.d.ts +3 -3
- package/build/runtime-cjs/cache/subscription.js +23 -21
- package/build/runtime-cjs/lib/config.d.ts +2 -1
- package/build/runtime-cjs/lib/scalars.d.ts +2 -2
- package/build/runtime-cjs/lib/scalars.js +9 -6
- package/build/runtime-cjs/lib/selection.d.ts +2 -0
- package/build/runtime-cjs/lib/selection.js +39 -0
- package/build/runtime-cjs/lib/types.d.ts +26 -16
- package/build/runtime-esm/cache/cache.js +38 -23
- package/build/runtime-esm/cache/lists.js +40 -26
- package/build/runtime-esm/cache/subscription.d.ts +3 -3
- package/build/runtime-esm/cache/subscription.js +23 -21
- package/build/runtime-esm/lib/config.d.ts +2 -1
- package/build/runtime-esm/lib/scalars.d.ts +2 -2
- package/build/runtime-esm/lib/scalars.js +9 -6
- package/build/runtime-esm/lib/selection.d.ts +2 -0
- package/build/runtime-esm/lib/selection.js +15 -0
- package/build/runtime-esm/lib/types.d.ts +26 -16
- package/build/test/index.d.ts +1 -2
- package/build/test-cjs/index.js +485 -195
- package/build/test-esm/index.js +485 -195
- package/build/vite-cjs/index.js +438 -193
- package/build/vite-esm/index.js +438 -193
- package/package.json +2 -2
- package/build/runtime-cjs/cache/tests/availability.test.js +0 -357
- package/build/runtime-cjs/cache/tests/gc.test.js +0 -271
- package/build/runtime-cjs/cache/tests/keys.test.js +0 -34
- package/build/runtime-cjs/cache/tests/list.test.js +0 -3390
- package/build/runtime-cjs/cache/tests/readwrite.test.js +0 -1076
- package/build/runtime-cjs/cache/tests/scalars.test.js +0 -181
- package/build/runtime-cjs/cache/tests/storage.test.js +0 -280
- package/build/runtime-cjs/cache/tests/subscriptions.test.js +0 -1469
- package/build/runtime-cjs/lib/scalars.test.js +0 -736
- package/build/runtime-esm/cache/tests/availability.test.js +0 -356
- package/build/runtime-esm/cache/tests/gc.test.js +0 -270
- package/build/runtime-esm/cache/tests/keys.test.js +0 -33
- package/build/runtime-esm/cache/tests/list.test.js +0 -3389
- package/build/runtime-esm/cache/tests/readwrite.test.js +0 -1075
- package/build/runtime-esm/cache/tests/scalars.test.js +0 -180
- package/build/runtime-esm/cache/tests/storage.test.js +0 -279
- package/build/runtime-esm/cache/tests/subscriptions.test.js +0 -1468
- package/build/runtime-esm/lib/scalars.test.js +0 -735
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { defaultConfigValues, computeID, keyFieldsForType } from "../lib/config";
|
|
2
2
|
import { deepEquals } from "../lib/deepEquals";
|
|
3
|
+
import { getFieldsForType } from "../lib/selection";
|
|
3
4
|
import { GarbageCollector } from "./gc";
|
|
4
5
|
import { ListManager } from "./lists";
|
|
5
6
|
import { InMemoryStorage } from "./storage";
|
|
@@ -134,8 +135,9 @@ class CacheInternal {
|
|
|
134
135
|
if (this._disabled) {
|
|
135
136
|
return [];
|
|
136
137
|
}
|
|
138
|
+
let targetSelection = getFieldsForType(selection, data["__typename"]);
|
|
137
139
|
for (const [field, value] of Object.entries(data)) {
|
|
138
|
-
if (!selection || !
|
|
140
|
+
if (!selection || !targetSelection[field]) {
|
|
139
141
|
throw new Error(
|
|
140
142
|
"Could not find field listing in selection for " + field + " @ " + JSON.stringify(selection)
|
|
141
143
|
);
|
|
@@ -143,11 +145,11 @@ class CacheInternal {
|
|
|
143
145
|
let {
|
|
144
146
|
type: linkedType,
|
|
145
147
|
keyRaw,
|
|
146
|
-
|
|
148
|
+
selection: fieldSelection,
|
|
147
149
|
operations,
|
|
148
150
|
abstract: isAbstract,
|
|
149
151
|
update
|
|
150
|
-
} =
|
|
152
|
+
} = targetSelection[field];
|
|
151
153
|
const key = evaluateKey(keyRaw, variables);
|
|
152
154
|
const currentSubscribers = this.subscriptions.get(parent, key);
|
|
153
155
|
const { value: previousValue, displayLayers } = this.storage.get(parent, key);
|
|
@@ -155,7 +157,7 @@ class CacheInternal {
|
|
|
155
157
|
if (displayLayer) {
|
|
156
158
|
this.lifetimes.resetLifetime(parent, key);
|
|
157
159
|
}
|
|
158
|
-
if (!
|
|
160
|
+
if (!fieldSelection) {
|
|
159
161
|
let newValue = value;
|
|
160
162
|
if (Array.isArray(value) && applyUpdates && update) {
|
|
161
163
|
if (update === "append") {
|
|
@@ -175,7 +177,7 @@ class CacheInternal {
|
|
|
175
177
|
}
|
|
176
178
|
const previousLinks = flattenList([previousValue]);
|
|
177
179
|
for (const link of previousLinks) {
|
|
178
|
-
this.subscriptions.remove(link,
|
|
180
|
+
this.subscriptions.remove(link, fieldSelection, currentSubscribers, variables);
|
|
179
181
|
}
|
|
180
182
|
layer.writeLink(parent, key, null);
|
|
181
183
|
toNotify.push(...currentSubscribers);
|
|
@@ -201,14 +203,14 @@ class CacheInternal {
|
|
|
201
203
|
if (previousValue && typeof previousValue === "string") {
|
|
202
204
|
this.subscriptions.remove(
|
|
203
205
|
previousValue,
|
|
204
|
-
|
|
206
|
+
fieldSelection,
|
|
205
207
|
currentSubscribers,
|
|
206
208
|
variables
|
|
207
209
|
);
|
|
208
210
|
}
|
|
209
211
|
this.subscriptions.addMany({
|
|
210
212
|
parent: linkedID,
|
|
211
|
-
selection:
|
|
213
|
+
selection: fieldSelection,
|
|
212
214
|
subscribers: currentSubscribers,
|
|
213
215
|
variables,
|
|
214
216
|
parentType: linkedType
|
|
@@ -218,14 +220,14 @@ class CacheInternal {
|
|
|
218
220
|
if (linkedID) {
|
|
219
221
|
this.writeSelection({
|
|
220
222
|
root,
|
|
221
|
-
selection:
|
|
223
|
+
selection: fieldSelection,
|
|
222
224
|
parent: linkedID,
|
|
223
225
|
data: value,
|
|
224
226
|
variables,
|
|
225
227
|
toNotify,
|
|
226
228
|
applyUpdates,
|
|
227
229
|
layer,
|
|
228
|
-
forceNotify
|
|
230
|
+
forceNotify
|
|
229
231
|
});
|
|
230
232
|
}
|
|
231
233
|
} else if (Array.isArray(value) && (typeof previousValue === "undefined" || Array.isArray(previousValue))) {
|
|
@@ -254,7 +256,7 @@ class CacheInternal {
|
|
|
254
256
|
key,
|
|
255
257
|
linkedType,
|
|
256
258
|
variables,
|
|
257
|
-
fields,
|
|
259
|
+
fields: fieldSelection,
|
|
258
260
|
layer,
|
|
259
261
|
forceNotify
|
|
260
262
|
});
|
|
@@ -304,7 +306,7 @@ class CacheInternal {
|
|
|
304
306
|
if (linkedIDs.includes(lostID) || !lostID) {
|
|
305
307
|
continue;
|
|
306
308
|
}
|
|
307
|
-
this.subscriptions.remove(lostID,
|
|
309
|
+
this.subscriptions.remove(lostID, fieldSelection, currentSubscribers, variables);
|
|
308
310
|
}
|
|
309
311
|
if (contentChanged || oldIDs.length === 0 && newIDs.length === 0) {
|
|
310
312
|
layer.writeLink(parent, key, linkedIDs);
|
|
@@ -315,7 +317,7 @@ class CacheInternal {
|
|
|
315
317
|
}
|
|
316
318
|
this.subscriptions.addMany({
|
|
317
319
|
parent: id,
|
|
318
|
-
selection:
|
|
320
|
+
selection: fieldSelection,
|
|
319
321
|
subscribers: currentSubscribers,
|
|
320
322
|
variables,
|
|
321
323
|
parentType: linkedType
|
|
@@ -340,9 +342,14 @@ class CacheInternal {
|
|
|
340
342
|
}
|
|
341
343
|
const targets = Array.isArray(value) ? value : [value];
|
|
342
344
|
for (const target of targets) {
|
|
343
|
-
if (operation.action === "insert" && target instanceof Object &&
|
|
344
|
-
this.cache.list(operation.list, parentID, operation.target === "all").when(operation.when).addToList(
|
|
345
|
-
|
|
345
|
+
if (operation.action === "insert" && target instanceof Object && fieldSelection && operation.list) {
|
|
346
|
+
this.cache.list(operation.list, parentID, operation.target === "all").when(operation.when).addToList(
|
|
347
|
+
fieldSelection,
|
|
348
|
+
target,
|
|
349
|
+
variables,
|
|
350
|
+
operation.position || "last"
|
|
351
|
+
);
|
|
352
|
+
} else if (operation.action === "remove" && target instanceof Object && fieldSelection && operation.list) {
|
|
346
353
|
this.cache.list(operation.list, parentID, operation.target === "all").when(operation.when).remove(target, variables);
|
|
347
354
|
} else if (operation.action === "delete" && operation.type) {
|
|
348
355
|
if (typeof target !== "string") {
|
|
@@ -353,8 +360,13 @@ class CacheInternal {
|
|
|
353
360
|
continue;
|
|
354
361
|
}
|
|
355
362
|
this.cache.delete(targetID);
|
|
356
|
-
} else if (operation.action === "toggle" && target instanceof Object &&
|
|
357
|
-
this.cache.list(operation.list, parentID, operation.target === "all").when(operation.when).toggleElement(
|
|
363
|
+
} else if (operation.action === "toggle" && target instanceof Object && fieldSelection && operation.list) {
|
|
364
|
+
this.cache.list(operation.list, parentID, operation.target === "all").when(operation.when).toggleElement(
|
|
365
|
+
fieldSelection,
|
|
366
|
+
target,
|
|
367
|
+
variables,
|
|
368
|
+
operation.position || "last"
|
|
369
|
+
);
|
|
358
370
|
}
|
|
359
371
|
}
|
|
360
372
|
}
|
|
@@ -374,9 +386,12 @@ class CacheInternal {
|
|
|
374
386
|
let hasData = false;
|
|
375
387
|
let partial = false;
|
|
376
388
|
let cascadeNull = false;
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
389
|
+
const typename = this.storage.get(parent, "__typename").value;
|
|
390
|
+
let targetSelection = getFieldsForType(selection, typename);
|
|
391
|
+
for (const [
|
|
392
|
+
attributeName,
|
|
393
|
+
{ type, keyRaw, selection: fieldSelection, nullable, list }
|
|
394
|
+
] of Object.entries(targetSelection)) {
|
|
380
395
|
const key = evaluateKey(keyRaw, variables);
|
|
381
396
|
const { value } = this.storage.get(parent, key);
|
|
382
397
|
let nextStep = stepsFromConnection;
|
|
@@ -399,7 +414,7 @@ class CacheInternal {
|
|
|
399
414
|
if (typeof value !== "undefined") {
|
|
400
415
|
hasData = true;
|
|
401
416
|
}
|
|
402
|
-
} else if (!
|
|
417
|
+
} else if (!fieldSelection) {
|
|
403
418
|
const fnUnmarshal = this.config?.scalars?.[type]?.unmarshal;
|
|
404
419
|
if (fnUnmarshal) {
|
|
405
420
|
target[attributeName] = fnUnmarshal(value);
|
|
@@ -409,7 +424,7 @@ class CacheInternal {
|
|
|
409
424
|
hasData = true;
|
|
410
425
|
} else if (Array.isArray(value)) {
|
|
411
426
|
const listValue = this.hydrateNestedList({
|
|
412
|
-
fields,
|
|
427
|
+
fields: fieldSelection,
|
|
413
428
|
variables,
|
|
414
429
|
linkedList: value,
|
|
415
430
|
stepsFromConnection: nextStep
|
|
@@ -424,7 +439,7 @@ class CacheInternal {
|
|
|
424
439
|
} else {
|
|
425
440
|
const objectFields = this.getSelection({
|
|
426
441
|
parent: value,
|
|
427
|
-
selection:
|
|
442
|
+
selection: fieldSelection,
|
|
428
443
|
variables,
|
|
429
444
|
stepsFromConnection: nextStep
|
|
430
445
|
});
|
|
@@ -142,23 +142,32 @@ class List {
|
|
|
142
142
|
let insertData = data;
|
|
143
143
|
if (this.connection) {
|
|
144
144
|
insertSelection = {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
keyRaw: "edges",
|
|
151
|
-
type: "ConnectionEdge",
|
|
152
|
-
update: where === "first" ? "prepend" : "append",
|
|
145
|
+
fields: {
|
|
146
|
+
newEntry: {
|
|
147
|
+
keyRaw: this.key,
|
|
148
|
+
type: "Connection",
|
|
149
|
+
selection: {
|
|
153
150
|
fields: {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
151
|
+
edges: {
|
|
152
|
+
keyRaw: "edges",
|
|
153
|
+
type: "ConnectionEdge",
|
|
154
|
+
update: where === "first" ? "prepend" : "append",
|
|
155
|
+
selection: {
|
|
156
|
+
fields: {
|
|
157
|
+
node: {
|
|
158
|
+
type: listType,
|
|
159
|
+
keyRaw: "node",
|
|
160
|
+
selection: {
|
|
161
|
+
...selection,
|
|
162
|
+
fields: {
|
|
163
|
+
...selection.fields,
|
|
164
|
+
__typename: {
|
|
165
|
+
keyRaw: "__typename",
|
|
166
|
+
type: "String"
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
162
171
|
}
|
|
163
172
|
}
|
|
164
173
|
}
|
|
@@ -174,15 +183,20 @@ class List {
|
|
|
174
183
|
};
|
|
175
184
|
} else {
|
|
176
185
|
insertSelection = {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
+
fields: {
|
|
187
|
+
newEntries: {
|
|
188
|
+
keyRaw: this.key,
|
|
189
|
+
type: listType,
|
|
190
|
+
update: where === "first" ? "prepend" : "append",
|
|
191
|
+
selection: {
|
|
192
|
+
...selection,
|
|
193
|
+
fields: {
|
|
194
|
+
...selection.fields,
|
|
195
|
+
__typename: {
|
|
196
|
+
keyRaw: "__typename",
|
|
197
|
+
type: "String"
|
|
198
|
+
}
|
|
199
|
+
}
|
|
186
200
|
}
|
|
187
201
|
}
|
|
188
202
|
}
|
|
@@ -242,7 +256,7 @@ class List {
|
|
|
242
256
|
const subscribers = this.cache._internal_unstable.subscriptions.get(this.recordID, this.key);
|
|
243
257
|
this.cache._internal_unstable.subscriptions.remove(
|
|
244
258
|
targetID,
|
|
245
|
-
this.connection ? this.selection.edges.
|
|
259
|
+
this.connection ? this.selection.fields.edges.selection : this.selection,
|
|
246
260
|
subscribers,
|
|
247
261
|
variables
|
|
248
262
|
);
|
|
@@ -16,10 +16,10 @@ export declare class InMemorySubscriptions {
|
|
|
16
16
|
[key: string]: GraphQLValue;
|
|
17
17
|
};
|
|
18
18
|
}): void;
|
|
19
|
-
addFieldSubscription({ id, key,
|
|
19
|
+
addFieldSubscription({ id, key, field, spec, parentType, variables, }: {
|
|
20
20
|
id: string;
|
|
21
21
|
key: string;
|
|
22
|
-
|
|
22
|
+
field: Required<SubscriptionSelection>['fields'][string];
|
|
23
23
|
spec: SubscriptionSpec;
|
|
24
24
|
parentType: string;
|
|
25
25
|
variables: GraphQLObject;
|
|
@@ -32,7 +32,7 @@ export declare class InMemorySubscriptions {
|
|
|
32
32
|
parentType: string;
|
|
33
33
|
}): void;
|
|
34
34
|
get(id: string, field: string): SubscriptionSpec[];
|
|
35
|
-
remove(id: string,
|
|
35
|
+
remove(id: string, selection: SubscriptionSelection, targets: SubscriptionSpec[], variables: {}, visited?: string[]): void;
|
|
36
36
|
private removeSubscribers;
|
|
37
37
|
removeAllSubscribers(id: string, targets?: SubscriptionSpec[], visited?: string[]): void;
|
|
38
38
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getFieldsForType } from "../lib/selection";
|
|
1
2
|
import { evaluateKey, flattenList } from "./stuff";
|
|
2
3
|
class InMemorySubscriptions {
|
|
3
4
|
cache;
|
|
@@ -14,18 +15,20 @@ class InMemorySubscriptions {
|
|
|
14
15
|
variables,
|
|
15
16
|
parentType
|
|
16
17
|
}) {
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
const __typename = this.cache._internal_unstable.storage.get(parent, "__typename").value;
|
|
19
|
+
let targetSelection = getFieldsForType(selection, __typename);
|
|
20
|
+
for (const fieldSelection of Object.values(targetSelection || {})) {
|
|
21
|
+
const { keyRaw, selection: innerSelection, type } = fieldSelection;
|
|
19
22
|
const key = evaluateKey(keyRaw, variables);
|
|
20
23
|
this.addFieldSubscription({
|
|
21
24
|
id: parent,
|
|
22
25
|
key,
|
|
23
|
-
|
|
26
|
+
field: fieldSelection,
|
|
24
27
|
spec,
|
|
25
28
|
parentType: parentType || spec.rootType,
|
|
26
29
|
variables
|
|
27
30
|
});
|
|
28
|
-
if (
|
|
31
|
+
if (innerSelection) {
|
|
29
32
|
const { value: linkedRecord } = this.cache._internal_unstable.storage.get(
|
|
30
33
|
parent,
|
|
31
34
|
key
|
|
@@ -38,7 +41,7 @@ class InMemorySubscriptions {
|
|
|
38
41
|
this.add({
|
|
39
42
|
parent: child,
|
|
40
43
|
spec,
|
|
41
|
-
selection:
|
|
44
|
+
selection: innerSelection,
|
|
42
45
|
variables,
|
|
43
46
|
parentType: type
|
|
44
47
|
});
|
|
@@ -49,7 +52,7 @@ class InMemorySubscriptions {
|
|
|
49
52
|
addFieldSubscription({
|
|
50
53
|
id,
|
|
51
54
|
key,
|
|
52
|
-
|
|
55
|
+
field,
|
|
53
56
|
spec,
|
|
54
57
|
parentType,
|
|
55
58
|
variables
|
|
@@ -76,8 +79,8 @@ class InMemorySubscriptions {
|
|
|
76
79
|
const counts = this.referenceCounts[id][key];
|
|
77
80
|
counts.set(spec.set, (counts.get(spec.set) || 0) + 1);
|
|
78
81
|
this.cache._internal_unstable.lifetimes.resetLifetime(id, key);
|
|
79
|
-
const {
|
|
80
|
-
if (
|
|
82
|
+
const { selection, list, filters } = field;
|
|
83
|
+
if (selection && list) {
|
|
81
84
|
this.cache._internal_unstable.lists.add({
|
|
82
85
|
name: list.name,
|
|
83
86
|
connection: list.connection,
|
|
@@ -85,7 +88,7 @@ class InMemorySubscriptions {
|
|
|
85
88
|
recordType: this.cache._internal_unstable.storage.get(id, "__typename")?.value || parentType,
|
|
86
89
|
listType: list.type,
|
|
87
90
|
key,
|
|
88
|
-
selection
|
|
91
|
+
selection,
|
|
89
92
|
filters: Object.entries(filters || {}).reduce((acc, [key2, { kind, value }]) => {
|
|
90
93
|
return {
|
|
91
94
|
...acc,
|
|
@@ -102,20 +105,21 @@ class InMemorySubscriptions {
|
|
|
102
105
|
subscribers,
|
|
103
106
|
parentType
|
|
104
107
|
}) {
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
let targetSelection = getFieldsForType(selection, parentType);
|
|
109
|
+
for (const fieldSelection of Object.values(targetSelection)) {
|
|
110
|
+
const { type: linkedType, keyRaw, selection: innerSelection } = fieldSelection;
|
|
107
111
|
const key = evaluateKey(keyRaw, variables);
|
|
108
112
|
for (const spec of subscribers) {
|
|
109
113
|
this.addFieldSubscription({
|
|
110
114
|
id: parent,
|
|
111
115
|
key,
|
|
112
|
-
|
|
116
|
+
field: fieldSelection,
|
|
113
117
|
spec,
|
|
114
118
|
parentType,
|
|
115
119
|
variables
|
|
116
120
|
});
|
|
117
121
|
}
|
|
118
|
-
if (
|
|
122
|
+
if (innerSelection) {
|
|
119
123
|
const { value: link } = this.cache._internal_unstable.storage.get(parent, key);
|
|
120
124
|
const children = !Array.isArray(link) ? [link] : flattenList(link);
|
|
121
125
|
for (const linkedRecord of children) {
|
|
@@ -124,7 +128,7 @@ class InMemorySubscriptions {
|
|
|
124
128
|
}
|
|
125
129
|
this.addMany({
|
|
126
130
|
parent: linkedRecord,
|
|
127
|
-
selection:
|
|
131
|
+
selection: innerSelection,
|
|
128
132
|
variables,
|
|
129
133
|
subscribers,
|
|
130
134
|
parentType: linkedType
|
|
@@ -136,22 +140,20 @@ class InMemorySubscriptions {
|
|
|
136
140
|
get(id, field) {
|
|
137
141
|
return this.subscribers[id]?.[field] || [];
|
|
138
142
|
}
|
|
139
|
-
remove(id,
|
|
143
|
+
remove(id, selection, targets, variables, visited = []) {
|
|
140
144
|
visited.push(id);
|
|
141
145
|
const linkedIDs = [];
|
|
142
|
-
for (const
|
|
143
|
-
const key = evaluateKey(
|
|
146
|
+
for (const fieldSelection of Object.values(selection.fields || {})) {
|
|
147
|
+
const key = evaluateKey(fieldSelection.keyRaw, variables);
|
|
144
148
|
this.removeSubscribers(id, key, targets);
|
|
145
|
-
if (!selection
|
|
149
|
+
if (!fieldSelection.selection?.fields) {
|
|
146
150
|
continue;
|
|
147
151
|
}
|
|
148
|
-
if (selection.list) {
|
|
149
|
-
}
|
|
150
152
|
const { value: previousValue } = this.cache._internal_unstable.storage.get(id, key);
|
|
151
153
|
const links = !Array.isArray(previousValue) ? [previousValue] : flattenList(previousValue);
|
|
152
154
|
for (const link of links) {
|
|
153
155
|
if (link !== null) {
|
|
154
|
-
linkedIDs.push([link, selection
|
|
156
|
+
linkedIDs.push([link, fieldSelection.selection || {}]);
|
|
155
157
|
}
|
|
156
158
|
}
|
|
157
159
|
}
|
|
@@ -87,8 +87,9 @@ export declare type ConfigFile = {
|
|
|
87
87
|
logLevel?: string;
|
|
88
88
|
/**
|
|
89
89
|
* A flag to specify the default fragment masking behavior.
|
|
90
|
+
* @default `enable`
|
|
90
91
|
*/
|
|
91
|
-
|
|
92
|
+
defaultFragmentMasking?: 'enable' | 'disable';
|
|
92
93
|
/**
|
|
93
94
|
* Configures the houdini plugin's schema polling behavior. By default, houdini will poll your APIs
|
|
94
95
|
* during development in order to keep it's definition of your schema up to date. The schemaPollingInterval
|
|
@@ -2,12 +2,12 @@ import { ConfigFile } from './config';
|
|
|
2
2
|
import { MutationArtifact, QueryArtifact, SubscriptionArtifact, SubscriptionSelection } from './types';
|
|
3
3
|
export declare function marshalSelection({ selection, data, }: {
|
|
4
4
|
selection: SubscriptionSelection;
|
|
5
|
-
data:
|
|
5
|
+
data: any;
|
|
6
6
|
}): Promise<{} | null | undefined>;
|
|
7
7
|
export declare function marshalInputs<T>({ artifact, input, rootType, }: {
|
|
8
8
|
artifact: QueryArtifact | MutationArtifact | SubscriptionArtifact;
|
|
9
9
|
input: unknown;
|
|
10
10
|
rootType?: string;
|
|
11
11
|
}): Promise<{} | null | undefined>;
|
|
12
|
-
export declare function unmarshalSelection(config: ConfigFile, selection: SubscriptionSelection, data:
|
|
12
|
+
export declare function unmarshalSelection(config: ConfigFile, selection: SubscriptionSelection, data: any): {} | null | undefined;
|
|
13
13
|
export declare function isScalar(config: ConfigFile, type: string): boolean;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getCurrentConfig } from "./config";
|
|
2
|
+
import { getFieldsForType } from "./selection";
|
|
2
3
|
async function marshalSelection({
|
|
3
4
|
selection,
|
|
4
5
|
data
|
|
@@ -10,15 +11,16 @@ async function marshalSelection({
|
|
|
10
11
|
if (Array.isArray(data)) {
|
|
11
12
|
return await Promise.all(data.map((val) => marshalSelection({ selection, data: val })));
|
|
12
13
|
}
|
|
14
|
+
const targetSelection = getFieldsForType(selection, data["__typename"]);
|
|
13
15
|
return Object.fromEntries(
|
|
14
16
|
await Promise.all(
|
|
15
17
|
Object.entries(data).map(async ([fieldName, value]) => {
|
|
16
|
-
const { type,
|
|
18
|
+
const { type, selection: selection2 } = targetSelection[fieldName];
|
|
17
19
|
if (!type) {
|
|
18
20
|
return [fieldName, value];
|
|
19
21
|
}
|
|
20
|
-
if (
|
|
21
|
-
return [fieldName, await marshalSelection({ selection:
|
|
22
|
+
if (selection2) {
|
|
23
|
+
return [fieldName, await marshalSelection({ selection: selection2, data: value })];
|
|
22
24
|
}
|
|
23
25
|
if (config.scalars?.[type]) {
|
|
24
26
|
const marshalFn = config.scalars[type].marshal;
|
|
@@ -84,16 +86,17 @@ function unmarshalSelection(config, selection, data) {
|
|
|
84
86
|
if (Array.isArray(data)) {
|
|
85
87
|
return data.map((val) => unmarshalSelection(config, selection, val));
|
|
86
88
|
}
|
|
89
|
+
const targetSelection = getFieldsForType(selection, data["__typename"]);
|
|
87
90
|
return Object.fromEntries(
|
|
88
91
|
Object.entries(data).map(([fieldName, value]) => {
|
|
89
|
-
const { type,
|
|
92
|
+
const { type, selection: selection2 } = targetSelection[fieldName];
|
|
90
93
|
if (!type) {
|
|
91
94
|
return [fieldName, value];
|
|
92
95
|
}
|
|
93
|
-
if (
|
|
96
|
+
if (selection2) {
|
|
94
97
|
return [
|
|
95
98
|
fieldName,
|
|
96
|
-
unmarshalSelection(config,
|
|
99
|
+
unmarshalSelection(config, selection2, value)
|
|
97
100
|
];
|
|
98
101
|
}
|
|
99
102
|
if (value === null) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function getFieldsForType(selection, __typename) {
|
|
2
|
+
let targetSelection = selection.fields || {};
|
|
3
|
+
if (selection.abstractFields && __typename) {
|
|
4
|
+
const mappedType = selection.abstractFields.typeMap[__typename];
|
|
5
|
+
if (mappedType) {
|
|
6
|
+
targetSelection = selection.abstractFields.fields[mappedType];
|
|
7
|
+
} else if (selection.abstractFields.fields[__typename]) {
|
|
8
|
+
targetSelection = selection.abstractFields.fields[__typename];
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return targetSelection;
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
getFieldsForType
|
|
15
|
+
};
|
|
@@ -107,25 +107,35 @@ export declare type GraphQLObject = {
|
|
|
107
107
|
};
|
|
108
108
|
export declare type GraphQLValue = number | string | boolean | null | GraphQLObject | GraphQLValue[] | undefined;
|
|
109
109
|
export declare type SubscriptionSelection = {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
nullable?: boolean;
|
|
113
|
-
keyRaw: string;
|
|
114
|
-
operations?: MutationOperation[];
|
|
115
|
-
list?: {
|
|
116
|
-
name: string;
|
|
117
|
-
connection: boolean;
|
|
110
|
+
fields?: {
|
|
111
|
+
[fieldName: string]: {
|
|
118
112
|
type: string;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
113
|
+
nullable?: boolean;
|
|
114
|
+
keyRaw: string;
|
|
115
|
+
operations?: MutationOperation[];
|
|
116
|
+
list?: {
|
|
117
|
+
name: string;
|
|
118
|
+
connection: boolean;
|
|
119
|
+
type: string;
|
|
120
|
+
};
|
|
121
|
+
update?: RefetchUpdateMode;
|
|
122
|
+
filters?: {
|
|
123
|
+
[key: string]: {
|
|
124
|
+
kind: 'Boolean' | 'String' | 'Float' | 'Int' | 'Variable';
|
|
125
|
+
value: string | number | boolean;
|
|
126
|
+
};
|
|
125
127
|
};
|
|
128
|
+
selection?: SubscriptionSelection;
|
|
129
|
+
abstract?: boolean;
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
abstractFields?: {
|
|
133
|
+
fields: {
|
|
134
|
+
[typeName: string]: SubscriptionSelection['fields'];
|
|
135
|
+
};
|
|
136
|
+
typeMap: {
|
|
137
|
+
[typeName: string]: string;
|
|
126
138
|
};
|
|
127
|
-
fields?: SubscriptionSelection;
|
|
128
|
-
abstract?: boolean;
|
|
129
139
|
};
|
|
130
140
|
};
|
|
131
141
|
export declare type SubscriptionSpec = {
|
package/build/test/index.d.ts
CHANGED
|
@@ -2,10 +2,9 @@ import { Config, CollectedGraphQLDocument } from '../lib';
|
|
|
2
2
|
import { ConfigFile } from '../runtime/lib/config';
|
|
3
3
|
export declare function testConfigFile(config?: Partial<ConfigFile>): ConfigFile;
|
|
4
4
|
export declare function testConfig(config?: Partial<ConfigFile>): Config;
|
|
5
|
-
declare type Partial<T> = {
|
|
5
|
+
export declare type Partial<T> = {
|
|
6
6
|
[P in keyof T]?: T[P];
|
|
7
7
|
};
|
|
8
8
|
export declare function pipelineTest(config: Config, documents: string[], shouldPass: boolean, testBody?: ((result: Error | Error[]) => void) | ((docs: CollectedGraphQLDocument[]) => void)): () => Promise<void>;
|
|
9
9
|
export declare function mockCollectedDoc(query: string): CollectedGraphQLDocument;
|
|
10
10
|
export declare function clearMock(): void;
|
|
11
|
-
export {};
|