relay-runtime 8.0.0 → 10.0.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.
Files changed (135) hide show
  1. package/handlers/RelayDefaultHandlerProvider.js.flow +41 -0
  2. package/handlers/connection/ConnectionHandler.js.flow +549 -0
  3. package/handlers/connection/ConnectionInterface.js.flow +92 -0
  4. package/handlers/connection/MutationHandlers.js.flow +88 -0
  5. package/index.js +1 -1
  6. package/index.js.flow +320 -0
  7. package/lib/handlers/RelayDefaultHandlerProvider.js +13 -2
  8. package/lib/handlers/connection/{RelayConnectionHandler.js → ConnectionHandler.js} +33 -35
  9. package/lib/handlers/connection/{RelayConnectionInterface.js → ConnectionInterface.js} +2 -2
  10. package/lib/handlers/connection/MutationHandlers.js +86 -0
  11. package/lib/index.js +15 -19
  12. package/lib/mutations/RelayDeclarativeMutationConfig.js +29 -52
  13. package/lib/mutations/RelayRecordProxy.js +1 -3
  14. package/lib/mutations/RelayRecordSourceMutator.js +2 -9
  15. package/lib/mutations/RelayRecordSourceProxy.js +2 -4
  16. package/lib/mutations/RelayRecordSourceSelectorProxy.js +1 -13
  17. package/lib/mutations/commitMutation.js +13 -3
  18. package/lib/mutations/validateMutation.js +16 -9
  19. package/lib/network/RelayObservable.js +9 -9
  20. package/lib/network/RelayQueryResponseCache.js +8 -6
  21. package/lib/query/PreloadableQueryRegistry.js +70 -0
  22. package/lib/query/fetchQueryInternal.js +31 -23
  23. package/lib/store/DataChecker.js +122 -110
  24. package/lib/store/RelayConcreteVariables.js +6 -2
  25. package/lib/store/RelayModernEnvironment.js +121 -67
  26. package/lib/store/RelayModernFragmentSpecResolver.js +12 -16
  27. package/lib/store/RelayModernQueryExecutor.js +389 -314
  28. package/lib/store/RelayModernRecord.js +14 -9
  29. package/lib/store/RelayModernSelector.js +7 -3
  30. package/lib/store/RelayModernStore.js +289 -484
  31. package/lib/store/RelayOperationTracker.js +35 -78
  32. package/lib/store/RelayOptimisticRecordSource.js +7 -5
  33. package/lib/store/RelayPublishQueue.js +6 -33
  34. package/lib/store/RelayReader.js +113 -45
  35. package/lib/store/RelayRecordSource.js +2 -9
  36. package/lib/store/RelayRecordSourceMapImpl.js +13 -18
  37. package/lib/store/RelayReferenceMarker.js +40 -60
  38. package/lib/store/RelayResponseNormalizer.js +158 -193
  39. package/lib/store/RelayStoreUtils.js +1 -0
  40. package/lib/store/StoreInspector.js +8 -8
  41. package/lib/store/TypeID.js +28 -0
  42. package/lib/store/cloneRelayScalarHandleSourceField.js +44 -0
  43. package/lib/store/normalizeRelayPayload.js +6 -2
  44. package/lib/store/readInlineData.js +1 -1
  45. package/lib/subscription/requestSubscription.js +5 -3
  46. package/lib/util/RelayConcreteNode.js +9 -6
  47. package/lib/util/RelayError.js +39 -9
  48. package/lib/util/RelayFeatureFlags.js +2 -5
  49. package/lib/util/RelayReplaySubject.js +3 -3
  50. package/lib/util/createPayloadFor3DField.js +7 -2
  51. package/lib/util/getRequestIdentifier.js +2 -2
  52. package/lib/util/recycleNodesInto.js +2 -6
  53. package/mutations/RelayDeclarativeMutationConfig.js.flow +380 -0
  54. package/mutations/RelayRecordProxy.js.flow +165 -0
  55. package/mutations/RelayRecordSourceMutator.js.flow +238 -0
  56. package/mutations/RelayRecordSourceProxy.js.flow +164 -0
  57. package/mutations/RelayRecordSourceSelectorProxy.js.flow +119 -0
  58. package/mutations/applyOptimisticMutation.js.flow +76 -0
  59. package/mutations/commitLocalUpdate.js.flow +24 -0
  60. package/mutations/commitMutation.js.flow +182 -0
  61. package/mutations/validateMutation.js.flow +213 -0
  62. package/network/ConvertToExecuteFunction.js.flow +49 -0
  63. package/network/RelayNetwork.js.flow +84 -0
  64. package/network/RelayNetworkTypes.js.flow +123 -0
  65. package/network/RelayObservable.js.flow +634 -0
  66. package/network/RelayQueryResponseCache.js.flow +111 -0
  67. package/package.json +1 -1
  68. package/query/GraphQLTag.js.flow +166 -0
  69. package/query/PreloadableQueryRegistry.js.flow +65 -0
  70. package/query/fetchQuery.js.flow +47 -0
  71. package/query/fetchQueryInternal.js.flow +348 -0
  72. package/relay-runtime.js +2 -2
  73. package/relay-runtime.min.js +2 -2
  74. package/store/ClientID.js.flow +43 -0
  75. package/store/DataChecker.js.flow +502 -0
  76. package/store/RelayConcreteVariables.js.flow +96 -0
  77. package/store/RelayModernEnvironment.js.flow +551 -0
  78. package/store/RelayModernFragmentSpecResolver.js.flow +426 -0
  79. package/store/RelayModernOperationDescriptor.js.flow +88 -0
  80. package/store/RelayModernQueryExecutor.js.flow +1321 -0
  81. package/store/RelayModernRecord.js.flow +403 -0
  82. package/store/RelayModernSelector.js.flow +455 -0
  83. package/store/RelayModernStore.js.flow +842 -0
  84. package/store/RelayOperationTracker.js.flow +164 -0
  85. package/store/RelayOptimisticRecordSource.js.flow +119 -0
  86. package/store/RelayPublishQueue.js.flow +401 -0
  87. package/store/RelayReader.js.flow +473 -0
  88. package/store/RelayRecordSource.js.flow +29 -0
  89. package/store/RelayRecordSourceMapImpl.js.flow +87 -0
  90. package/store/RelayRecordState.js.flow +37 -0
  91. package/store/RelayReferenceMarker.js.flow +257 -0
  92. package/store/RelayResponseNormalizer.js.flow +680 -0
  93. package/store/RelayStoreTypes.js.flow +899 -0
  94. package/store/RelayStoreUtils.js.flow +219 -0
  95. package/store/StoreInspector.js.flow +171 -0
  96. package/store/TypeID.js.flow +28 -0
  97. package/store/ViewerPattern.js.flow +26 -0
  98. package/store/cloneRelayHandleSourceField.js.flow +66 -0
  99. package/store/cloneRelayScalarHandleSourceField.js.flow +62 -0
  100. package/store/createFragmentSpecResolver.js.flow +55 -0
  101. package/store/createRelayContext.js.flow +44 -0
  102. package/store/defaultGetDataID.js.flow +27 -0
  103. package/store/hasOverlappingIDs.js.flow +34 -0
  104. package/store/isRelayModernEnvironment.js.flow +27 -0
  105. package/store/normalizeRelayPayload.js.flow +51 -0
  106. package/store/readInlineData.js.flow +75 -0
  107. package/subscription/requestSubscription.js.flow +100 -0
  108. package/util/JSResourceTypes.flow.js.flow +20 -0
  109. package/util/NormalizationNode.js.flow +198 -0
  110. package/util/ReaderNode.js.flow +208 -0
  111. package/util/RelayConcreteNode.js.flow +93 -0
  112. package/util/RelayDefaultHandleKey.js.flow +17 -0
  113. package/util/RelayError.js.flow +62 -0
  114. package/util/RelayFeatureFlags.js.flow +30 -0
  115. package/util/RelayProfiler.js.flow +284 -0
  116. package/util/RelayReplaySubject.js.flow +135 -0
  117. package/util/RelayRuntimeTypes.js.flow +72 -0
  118. package/util/createPayloadFor3DField.js.flow +43 -0
  119. package/util/deepFreeze.js.flow +36 -0
  120. package/util/generateID.js.flow +21 -0
  121. package/util/getFragmentIdentifier.js.flow +52 -0
  122. package/util/getRelayHandleKey.js.flow +41 -0
  123. package/util/getRequestIdentifier.js.flow +42 -0
  124. package/util/isPromise.js.flow +21 -0
  125. package/util/isScalarAndEqual.js.flow +26 -0
  126. package/util/recycleNodesInto.js.flow +76 -0
  127. package/util/resolveImmediate.js.flow +30 -0
  128. package/util/stableCopy.js.flow +35 -0
  129. package/lib/handlers/RelayDefaultMissingFieldHandlers.js +0 -26
  130. package/lib/handlers/getRelayDefaultMissingFieldHandlers.js +0 -36
  131. package/lib/query/RelayModernGraphQLTag.js +0 -104
  132. package/lib/store/RelayConnection.js +0 -37
  133. package/lib/store/RelayConnectionResolver.js +0 -178
  134. package/lib/store/RelayRecordSourceObjectImpl.js +0 -79
  135. package/lib/util/getFragmentSpecIdentifier.js +0 -27
@@ -0,0 +1,455 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow strict-local
8
+ * @format
9
+ */
10
+
11
+ // flowlint ambiguous-object-type:error
12
+
13
+ 'use strict';
14
+
15
+ const areEqual = require('areEqual');
16
+ const invariant = require('invariant');
17
+ const warning = require('warning');
18
+
19
+ const {getFragmentVariables} = require('./RelayConcreteVariables');
20
+ const {
21
+ FRAGMENT_OWNER_KEY,
22
+ FRAGMENTS_KEY,
23
+ ID_KEY,
24
+ IS_WITHIN_UNMATCHED_TYPE_REFINEMENT,
25
+ } = require('./RelayStoreUtils');
26
+
27
+ import type {NormalizationSelectableNode} from '../util/NormalizationNode';
28
+ import type {ReaderFragment} from '../util/ReaderNode';
29
+ import type {DataID, Variables} from '../util/RelayRuntimeTypes';
30
+ import type {
31
+ NormalizationSelector,
32
+ PluralReaderSelector,
33
+ ReaderSelector,
34
+ RequestDescriptor,
35
+ SingularReaderSelector,
36
+ } from './RelayStoreTypes';
37
+
38
+ /**
39
+ * @public
40
+ *
41
+ * Given the result `item` from a parent that fetched `fragment`, creates a
42
+ * selector that can be used to read the results of that fragment for that item.
43
+ *
44
+ * Example:
45
+ *
46
+ * Given two fragments as follows:
47
+ *
48
+ * ```
49
+ * fragment Parent on User {
50
+ * id
51
+ * ...Child
52
+ * }
53
+ * fragment Child on User {
54
+ * name
55
+ * }
56
+ * ```
57
+ *
58
+ * And given some object `parent` that is the results of `Parent` for id "4",
59
+ * the results of `Child` can be accessed by first getting a selector and then
60
+ * using that selector to `lookup()` the results against the environment:
61
+ *
62
+ * ```
63
+ * const childSelector = getSingularSelector(queryVariables, Child, parent);
64
+ * const childData = environment.lookup(childSelector).data;
65
+ * ```
66
+ */
67
+ function getSingularSelector(
68
+ fragment: ReaderFragment,
69
+ item: mixed,
70
+ ): ?SingularReaderSelector {
71
+ invariant(
72
+ typeof item === 'object' && item !== null && !Array.isArray(item),
73
+ 'RelayModernSelector: Expected value for fragment `%s` to be an object, got ' +
74
+ '`%s`.',
75
+ fragment.name,
76
+ JSON.stringify(item),
77
+ );
78
+ const dataID = item[ID_KEY];
79
+ const fragments = item[FRAGMENTS_KEY];
80
+ const mixedOwner = item[FRAGMENT_OWNER_KEY];
81
+ const isWithinUnmatchedTypeRefinement =
82
+ item[IS_WITHIN_UNMATCHED_TYPE_REFINEMENT] === true;
83
+ if (
84
+ typeof dataID === 'string' &&
85
+ typeof fragments === 'object' &&
86
+ fragments !== null &&
87
+ typeof fragments[fragment.name] === 'object' &&
88
+ fragments[fragment.name] !== null &&
89
+ typeof mixedOwner === 'object' &&
90
+ mixedOwner !== null
91
+ ) {
92
+ const owner: RequestDescriptor = (mixedOwner: $FlowFixMe);
93
+ const argumentVariables = fragments[fragment.name];
94
+
95
+ const fragmentVariables = getFragmentVariables(
96
+ fragment,
97
+ owner.variables,
98
+ argumentVariables,
99
+ );
100
+ return createReaderSelector(
101
+ fragment,
102
+ dataID,
103
+ fragmentVariables,
104
+ owner,
105
+ isWithinUnmatchedTypeRefinement,
106
+ );
107
+ }
108
+
109
+ if (__DEV__) {
110
+ let stringifiedItem = JSON.stringify(item);
111
+ if (stringifiedItem.length > 499) {
112
+ stringifiedItem = stringifiedItem.substr(0, 498) + '\u2026';
113
+ }
114
+
115
+ warning(
116
+ false,
117
+ 'RelayModernSelector: Expected object to contain data for fragment `%s`, got ' +
118
+ '`%s`. Make sure that the parent operation/fragment included fragment ' +
119
+ '`...%s` without `@relay(mask: false)`.',
120
+ fragment.name,
121
+ stringifiedItem,
122
+ fragment.name,
123
+ );
124
+ }
125
+
126
+ return null;
127
+ }
128
+
129
+ /**
130
+ * @public
131
+ *
132
+ * Given the result `items` from a parent that fetched `fragment`, creates a
133
+ * selector that can be used to read the results of that fragment on those
134
+ * items. This is similar to `getSingularSelector` but for "plural" fragments that
135
+ * expect an array of results and therefore return an array of selectors.
136
+ */
137
+ function getPluralSelector(
138
+ fragment: ReaderFragment,
139
+ items: $ReadOnlyArray<mixed>,
140
+ ): ?PluralReaderSelector {
141
+ let selectors = null;
142
+ items.forEach((item, ii) => {
143
+ const selector = item != null ? getSingularSelector(fragment, item) : null;
144
+ if (selector != null) {
145
+ selectors = selectors || [];
146
+ selectors.push(selector);
147
+ }
148
+ });
149
+ if (selectors == null) {
150
+ return null;
151
+ } else {
152
+ return {
153
+ kind: 'PluralReaderSelector',
154
+ selectors,
155
+ };
156
+ }
157
+ }
158
+
159
+ function getSelector(
160
+ fragment: ReaderFragment,
161
+ item: mixed | Array<mixed>,
162
+ ): ?ReaderSelector {
163
+ if (item == null) {
164
+ return item;
165
+ } else if (fragment.metadata && fragment.metadata.plural === true) {
166
+ invariant(
167
+ Array.isArray(item),
168
+ 'RelayModernSelector: Expected value for fragment `%s` to be an array, got `%s`. ' +
169
+ 'Remove `@relay(plural: true)` from fragment `%s` to allow the prop to be an object.',
170
+ fragment.name,
171
+ JSON.stringify(item),
172
+ fragment.name,
173
+ );
174
+ return getPluralSelector(fragment, item);
175
+ } else {
176
+ invariant(
177
+ !Array.isArray(item),
178
+ 'RelayModernSelector: Expected value for fragment `%s` to be an object, got `%s`. ' +
179
+ 'Add `@relay(plural: true)` to fragment `%s` to allow the prop to be an array of items.',
180
+ fragment.name,
181
+ JSON.stringify(item),
182
+ fragment.name,
183
+ );
184
+ return getSingularSelector(fragment, item);
185
+ }
186
+ }
187
+
188
+ /**
189
+ * @public
190
+ *
191
+ * Given a mapping of keys -> results and a mapping of keys -> fragments,
192
+ * extracts the selectors for those fragments from the results.
193
+ *
194
+ * The canonical use-case for this function is ReactRelayFragmentContainer, which
195
+ * uses this function to convert (props, fragments) into selectors so that it
196
+ * can read the results to pass to the inner component.
197
+ */
198
+ function getSelectorsFromObject(
199
+ fragments: {[key: string]: ReaderFragment, ...},
200
+ object: {[key: string]: mixed, ...},
201
+ ): {[key: string]: ?ReaderSelector, ...} {
202
+ const selectors = {};
203
+ for (const key in fragments) {
204
+ if (fragments.hasOwnProperty(key)) {
205
+ const fragment = fragments[key];
206
+ const item = object[key];
207
+ selectors[key] = getSelector(fragment, item);
208
+ }
209
+ }
210
+ return selectors;
211
+ }
212
+
213
+ /**
214
+ * @public
215
+ *
216
+ * Given a mapping of keys -> results and a mapping of keys -> fragments,
217
+ * extracts a mapping of keys -> id(s) of the results.
218
+ *
219
+ * Similar to `getSelectorsFromObject()`, this function can be useful in
220
+ * determining the "identity" of the props passed to a component.
221
+ */
222
+ function getDataIDsFromObject(
223
+ fragments: {[key: string]: ReaderFragment, ...},
224
+ object: {[key: string]: mixed, ...},
225
+ ): {[key: string]: ?(DataID | Array<DataID>), ...} {
226
+ const ids = {};
227
+ for (const key in fragments) {
228
+ if (fragments.hasOwnProperty(key)) {
229
+ const fragment = fragments[key];
230
+ const item = object[key];
231
+ ids[key] = getDataIDsFromFragment(fragment, item);
232
+ }
233
+ }
234
+ return ids;
235
+ }
236
+
237
+ function getDataIDsFromFragment(
238
+ fragment: ReaderFragment,
239
+ item: mixed | Array<mixed>,
240
+ ): ?DataID | ?$ReadOnlyArray<DataID> {
241
+ if (item == null) {
242
+ return item;
243
+ } else if (fragment.metadata && fragment.metadata.plural === true) {
244
+ invariant(
245
+ Array.isArray(item),
246
+ 'RelayModernSelector: Expected value for fragment `%s` to be an array, got `%s`. ' +
247
+ 'Remove `@relay(plural: true)` from fragment `%s` to allow the prop to be an object.',
248
+ fragment.name,
249
+ JSON.stringify(item),
250
+ fragment.name,
251
+ );
252
+ return getDataIDs(fragment, item);
253
+ } else {
254
+ invariant(
255
+ !Array.isArray(item),
256
+ 'RelayModernFragmentSpecResolver: Expected value for fragment `%s` to be an object, got `%s`. ' +
257
+ 'Add `@relay(plural: true)` to fragment `%s` to allow the prop to be an array of items.',
258
+ fragment.name,
259
+ JSON.stringify(item),
260
+ fragment.name,
261
+ );
262
+ return getDataID(fragment, item);
263
+ }
264
+ }
265
+
266
+ /**
267
+ * @internal
268
+ */
269
+ function getDataIDs(
270
+ fragment: ReaderFragment,
271
+ items: $ReadOnlyArray<mixed>,
272
+ ): ?$ReadOnlyArray<DataID> {
273
+ let ids = null;
274
+ items.forEach(item => {
275
+ const id = item != null ? getDataID(fragment, item) : null;
276
+ if (id != null) {
277
+ ids = ids || [];
278
+ ids.push(id);
279
+ }
280
+ });
281
+ return ids;
282
+ }
283
+
284
+ /**
285
+ * @internal
286
+ */
287
+ function getDataID(fragment: ReaderFragment, item: mixed): ?DataID {
288
+ invariant(
289
+ typeof item === 'object' && item !== null && !Array.isArray(item),
290
+ 'RelayModernSelector: Expected value for fragment `%s` to be an object, got ' +
291
+ '`%s`.',
292
+ fragment.name,
293
+ JSON.stringify(item),
294
+ );
295
+ const dataID = item[ID_KEY];
296
+ if (typeof dataID === 'string') {
297
+ return dataID;
298
+ }
299
+ warning(
300
+ false,
301
+ 'RelayModernSelector: Expected object to contain data for fragment `%s`, got ' +
302
+ '`%s`. Make sure that the parent operation/fragment included fragment ' +
303
+ '`...%s` without `@relay(mask: false)`, or `null` is passed as the fragment ' +
304
+ "reference for `%s` if it's conditonally included and the condition isn't met.",
305
+ fragment.name,
306
+ JSON.stringify(item),
307
+ fragment.name,
308
+ fragment.name,
309
+ );
310
+ return null;
311
+ }
312
+
313
+ /**
314
+ * @public
315
+ *
316
+ * Given a mapping of keys -> results and a mapping of keys -> fragments,
317
+ * extracts the merged variables that would be in scope for those
318
+ * fragments/results.
319
+ *
320
+ * This can be useful in determing what varaibles were used to fetch the data
321
+ * for a Relay container, for example.
322
+ */
323
+ function getVariablesFromObject(
324
+ fragments: {[key: string]: ReaderFragment, ...},
325
+ object: {[key: string]: mixed, ...},
326
+ ): Variables {
327
+ const variables = {};
328
+ for (const key in fragments) {
329
+ if (fragments.hasOwnProperty(key)) {
330
+ const fragment = fragments[key];
331
+ const item = object[key];
332
+ const itemVariables = getVariablesFromFragment(fragment, item);
333
+ Object.assign(variables, itemVariables);
334
+ }
335
+ }
336
+ return variables;
337
+ }
338
+
339
+ function getVariablesFromFragment(
340
+ fragment: ReaderFragment,
341
+ item: mixed | $ReadOnlyArray<mixed>,
342
+ ): Variables {
343
+ if (item == null) {
344
+ return {};
345
+ } else if (fragment.metadata?.plural === true) {
346
+ invariant(
347
+ Array.isArray(item),
348
+ 'RelayModernSelector: Expected value for fragment `%s` to be an array, got `%s`. ' +
349
+ 'Remove `@relay(plural: true)` from fragment `%s` to allow the prop to be an object.',
350
+ fragment.name,
351
+ JSON.stringify(item),
352
+ fragment.name,
353
+ );
354
+
355
+ return getVariablesFromPluralFragment(fragment, item);
356
+ } else {
357
+ invariant(
358
+ !Array.isArray(item),
359
+ 'RelayModernFragmentSpecResolver: Expected value for fragment `%s` to be an object, got `%s`. ' +
360
+ 'Add `@relay(plural: true)` to fragment `%s` to allow the prop to be an array of items.',
361
+ fragment.name,
362
+ JSON.stringify(item),
363
+ fragment.name,
364
+ );
365
+
366
+ return getVariablesFromSingularFragment(fragment, item) || {};
367
+ }
368
+ }
369
+
370
+ function getVariablesFromSingularFragment(
371
+ fragment: ReaderFragment,
372
+ item: mixed,
373
+ ): ?Variables {
374
+ const selector = getSingularSelector(fragment, item);
375
+ if (!selector) {
376
+ return null;
377
+ }
378
+ return selector.variables;
379
+ }
380
+
381
+ function getVariablesFromPluralFragment(
382
+ fragment: ReaderFragment,
383
+ items: $ReadOnlyArray<mixed>,
384
+ ): Variables {
385
+ const variables = {};
386
+ items.forEach((value, ii) => {
387
+ if (value != null) {
388
+ const itemVariables = getVariablesFromSingularFragment(fragment, value);
389
+ if (itemVariables != null) {
390
+ Object.assign(variables, itemVariables);
391
+ }
392
+ }
393
+ });
394
+ return variables;
395
+ }
396
+
397
+ /**
398
+ * @public
399
+ *
400
+ * Determine if two selectors are equal (represent the same selection). Note
401
+ * that this function returns `false` when the two queries/fragments are
402
+ * different objects, even if they select the same fields.
403
+ */
404
+ function areEqualSelectors(
405
+ thisSelector: SingularReaderSelector,
406
+ thatSelector: SingularReaderSelector,
407
+ ): boolean {
408
+ return (
409
+ thisSelector.owner === thatSelector.owner &&
410
+ thisSelector.dataID === thatSelector.dataID &&
411
+ thisSelector.node === thatSelector.node &&
412
+ areEqual(thisSelector.variables, thatSelector.variables)
413
+ );
414
+ }
415
+
416
+ function createReaderSelector(
417
+ fragment: ReaderFragment,
418
+ dataID: DataID,
419
+ variables: Variables,
420
+ request: RequestDescriptor,
421
+ isWithinUnmatchedTypeRefinement: boolean = false,
422
+ ): SingularReaderSelector {
423
+ return {
424
+ kind: 'SingularReaderSelector',
425
+ dataID,
426
+ isWithinUnmatchedTypeRefinement,
427
+ node: fragment,
428
+ variables,
429
+ owner: request,
430
+ };
431
+ }
432
+
433
+ function createNormalizationSelector(
434
+ node: NormalizationSelectableNode,
435
+ dataID: DataID,
436
+ variables: Variables,
437
+ ): NormalizationSelector {
438
+ return {dataID, node, variables};
439
+ }
440
+
441
+ module.exports = {
442
+ areEqualSelectors,
443
+ createReaderSelector,
444
+ createNormalizationSelector,
445
+ getDataIDsFromFragment,
446
+ getDataIDsFromObject,
447
+ getSingularSelector,
448
+ getPluralSelector,
449
+ getSelector,
450
+ getSelectorsFromObject,
451
+ getVariablesFromSingularFragment,
452
+ getVariablesFromPluralFragment,
453
+ getVariablesFromFragment,
454
+ getVariablesFromObject,
455
+ };