relay-runtime 13.0.3 → 13.2.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.
Files changed (50) hide show
  1. package/index.js +1 -1
  2. package/index.js.flow +4 -2
  3. package/lib/index.js +3 -3
  4. package/lib/mutations/readUpdatableQuery_EXPERIMENTAL.js +3 -4
  5. package/lib/query/GraphQLTag.js +13 -0
  6. package/lib/query/fetchQuery.js +2 -5
  7. package/lib/store/RelayModernEnvironment.js +3 -3
  8. package/lib/store/RelayModernFragmentSpecResolver.js +6 -6
  9. package/lib/store/RelayModernSelector.js +16 -2
  10. package/lib/store/RelayReader.js +71 -6
  11. package/lib/store/RelayStoreSubscriptions.js +4 -2
  12. package/lib/store/RelayStoreUtils.js +1 -0
  13. package/lib/store/ResolverCache.js +25 -13
  14. package/lib/store/experimental-live-resolvers/LiveResolverCache.js +316 -0
  15. package/lib/store/experimental-live-resolvers/LiveResolverStore.js +787 -0
  16. package/lib/store/hasOverlappingIDs.js +1 -1
  17. package/lib/util/RelayConcreteNode.js +2 -0
  18. package/lib/util/RelayFeatureFlags.js +0 -3
  19. package/lib/util/handlePotentialSnapshotErrors.js +73 -0
  20. package/mutations/RelayRecordSourceProxy.js.flow +7 -3
  21. package/mutations/RelayRecordSourceSelectorProxy.js.flow +7 -3
  22. package/mutations/readUpdatableQuery_EXPERIMENTAL.js.flow +14 -12
  23. package/network/RelayNetworkTypes.js.flow +1 -1
  24. package/package.json +1 -1
  25. package/query/GraphQLTag.js.flow +38 -3
  26. package/query/fetchQuery.js.flow +6 -4
  27. package/relay-runtime.js +2 -2
  28. package/relay-runtime.min.js +2 -2
  29. package/store/RelayModernEnvironment.js.flow +3 -3
  30. package/store/RelayModernFragmentSpecResolver.js.flow +11 -7
  31. package/store/RelayModernSelector.js.flow +32 -8
  32. package/store/RelayReader.js.flow +65 -23
  33. package/store/RelayResponseNormalizer.js.flow +1 -1
  34. package/store/RelayStoreSubscriptions.js.flow +2 -0
  35. package/store/RelayStoreTypes.js.flow +22 -8
  36. package/store/RelayStoreUtils.js.flow +2 -1
  37. package/store/ResolverCache.js.flow +45 -10
  38. package/store/defaultGetDataID.js.flow +1 -1
  39. package/store/experimental-live-resolvers/LiveResolverCache.js.flow +410 -0
  40. package/store/experimental-live-resolvers/LiveResolverStore.js.flow +822 -0
  41. package/store/hasOverlappingIDs.js.flow +1 -1
  42. package/util/ReaderNode.js.flow +17 -1
  43. package/util/RelayConcreteNode.js.flow +9 -1
  44. package/util/RelayFeatureFlags.js.flow +0 -6
  45. package/util/RelayRuntimeTypes.js.flow +20 -1
  46. package/util/deepFreeze.js.flow +1 -1
  47. package/util/handlePotentialSnapshotErrors.js.flow +63 -0
  48. package/util/isEmptyObject.js.flow +1 -1
  49. package/lib/util/reportMissingRequiredFields.js +0 -48
  50. package/util/reportMissingRequiredFields.js.flow +0 -51
@@ -13,7 +13,7 @@
13
13
  var ITERATOR_KEY = Symbol.iterator;
14
14
 
15
15
  function hasOverlappingIDs(seenRecords, updatedRecordIDs) {
16
- // $FlowFixMe: Set is an iterable type, accessing its iterator is allowed.
16
+ // $FlowFixMe[incompatible-use]: Set is an iterable type, accessing its iterator is allowed.
17
17
  var iterator = seenRecords[ITERATOR_KEY]();
18
18
  var next = iterator.next();
19
19
 
@@ -44,6 +44,7 @@ var RelayConcreteNode = {
44
44
  LOCAL_ARGUMENT: 'LocalArgument',
45
45
  MODULE_IMPORT: 'ModuleImport',
46
46
  RELAY_RESOLVER: 'RelayResolver',
47
+ RELAY_LIVE_RESOLVER: 'RelayLiveResolver',
47
48
  REQUIRED_FIELD: 'RequiredField',
48
49
  OBJECT_VALUE: 'ObjectValue',
49
50
  OPERATION: 'Operation',
@@ -54,6 +55,7 @@ var RelayConcreteNode = {
54
55
  SPLIT_OPERATION: 'SplitOperation',
55
56
  STREAM: 'Stream',
56
57
  TYPE_DISCRIMINATOR: 'TypeDiscriminator',
58
+ UPDATABLE_QUERY: 'UpdatableQuery',
57
59
  VARIABLE: 'Variable'
58
60
  };
59
61
  module.exports = RelayConcreteNode;
@@ -11,7 +11,6 @@
11
11
  'use strict';
12
12
 
13
13
  var RelayFeatureFlags = {
14
- DELAY_CLEANUP_OF_PENDING_PRELOAD_QUERIES: false,
15
14
  ENABLE_CLIENT_EDGES: false,
16
15
  ENABLE_VARIABLE_CONNECTION_KEY: false,
17
16
  ENABLE_PARTIAL_RENDERING_DEFAULT: true,
@@ -24,9 +23,7 @@ var RelayFeatureFlags = {
24
23
  ENABLE_NOTIFY_SUBSCRIPTION: false,
25
24
  BATCH_ASYNC_MODULE_UPDATES_FN: null,
26
25
  ENABLE_CONTAINERS_SUBSCRIBE_ON_COMMIT: false,
27
- ENABLE_QUERY_RENDERER_OFFSCREEN_SUPPORT: false,
28
26
  MAX_DATA_ID_LENGTH: null,
29
- REFACTOR_SUSPENSE_RESOURCE: true,
30
27
  STRING_INTERN_LEVEL: 0,
31
28
  USE_REACT_CACHE: false
32
29
  };
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and 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
+ *
8
+ * @emails oncall+relay
9
+ * @format
10
+ */
11
+ 'use strict';
12
+
13
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
14
+
15
+ var _createForOfIteratorHelper2 = _interopRequireDefault(require("@babel/runtime/helpers/createForOfIteratorHelper"));
16
+
17
+ function handlePotentialSnapshotErrors(environment, missingRequiredFields, relayResolverErrors) {
18
+ var _iterator = (0, _createForOfIteratorHelper2["default"])(relayResolverErrors),
19
+ _step;
20
+
21
+ try {
22
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
23
+ var resolverError = _step.value;
24
+ environment.requiredFieldLogger({
25
+ kind: 'relay_resolver.error',
26
+ owner: resolverError.field.owner,
27
+ fieldPath: resolverError.field.path,
28
+ error: resolverError.error
29
+ });
30
+ }
31
+ } catch (err) {
32
+ _iterator.e(err);
33
+ } finally {
34
+ _iterator.f();
35
+ }
36
+
37
+ if (missingRequiredFields != null) {
38
+ switch (missingRequiredFields.action) {
39
+ case 'THROW':
40
+ {
41
+ var _missingRequiredField = missingRequiredFields.field,
42
+ path = _missingRequiredField.path,
43
+ owner = _missingRequiredField.owner; // This gives the consumer the chance to throw their own error if they so wish.
44
+
45
+ environment.requiredFieldLogger({
46
+ kind: 'missing_field.throw',
47
+ owner: owner,
48
+ fieldPath: path
49
+ });
50
+ throw new Error("Relay: Missing @required value at path '".concat(path, "' in '").concat(owner, "'."));
51
+ }
52
+
53
+ case 'LOG':
54
+ missingRequiredFields.fields.forEach(function (_ref) {
55
+ var path = _ref.path,
56
+ owner = _ref.owner;
57
+ environment.requiredFieldLogger({
58
+ kind: 'missing_field.log',
59
+ owner: owner,
60
+ fieldPath: path
61
+ });
62
+ });
63
+ break;
64
+
65
+ default:
66
+ {
67
+ missingRequiredFields.action;
68
+ }
69
+ }
70
+ }
71
+ }
72
+
73
+ module.exports = handlePotentialSnapshotErrors;
@@ -22,7 +22,11 @@ import type {
22
22
  RecordSource,
23
23
  RecordSourceProxy,
24
24
  } from '../store/RelayStoreTypes';
25
- import type {DataID, OperationType} from '../util/RelayRuntimeTypes';
25
+ import type {
26
+ DataID,
27
+ UpdatableQuery,
28
+ UpdatableQueryType,
29
+ } from '../util/RelayRuntimeTypes';
26
30
  import type RelayRecordSourceMutator from './RelayRecordSourceMutator';
27
31
 
28
32
  const RelayModernRecord = require('../store/RelayModernRecord');
@@ -163,8 +167,8 @@ class RelayRecordSourceProxy implements RecordSourceProxy {
163
167
  return this._idsMarkedForInvalidation;
164
168
  }
165
169
 
166
- readUpdatableQuery_EXPERIMENTAL<TQuery: OperationType>(
167
- query: GraphQLTaggedNode,
170
+ readUpdatableQuery_EXPERIMENTAL<TQuery: UpdatableQueryType>(
171
+ query: UpdatableQuery<TQuery['variables'], TQuery['response']>,
168
172
  variables: TQuery['variables'],
169
173
  ): TQuery['response'] {
170
174
  return readUpdatableQuery_EXPERIMENTAL(query, variables, this);
@@ -20,7 +20,11 @@ import type {
20
20
  SingularReaderSelector,
21
21
  } from '../store/RelayStoreTypes';
22
22
  import type {ReaderLinkedField} from '../util/ReaderNode';
23
- import type {DataID, OperationType} from '../util/RelayRuntimeTypes';
23
+ import type {
24
+ DataID,
25
+ UpdatableQuery,
26
+ UpdatableQueryType,
27
+ } from '../util/RelayRuntimeTypes';
24
28
  import type RelayRecordSourceMutator from './RelayRecordSourceMutator';
25
29
 
26
30
  const {ROOT_TYPE, getStorageKey} = require('../store/RelayStoreUtils');
@@ -123,8 +127,8 @@ class RelayRecordSourceSelectorProxy implements RecordSourceSelectorProxy {
123
127
  this.__recordSource.invalidateStore();
124
128
  }
125
129
 
126
- readUpdatableQuery_EXPERIMENTAL<TQuery: OperationType>(
127
- query: GraphQLTaggedNode,
130
+ readUpdatableQuery_EXPERIMENTAL<TQuery: UpdatableQueryType>(
131
+ query: UpdatableQuery<TQuery['variables'], TQuery['response']>,
128
132
  variables: TQuery['variables'],
129
133
  ): TQuery['response'] {
130
134
  return readUpdatableQuery_EXPERIMENTAL(query, variables, this);
@@ -16,27 +16,29 @@
16
16
  import type {GraphQLTaggedNode} from '../query/GraphQLTag';
17
17
  import type {RecordProxy, RecordSourceProxy} from '../store/RelayStoreTypes';
18
18
  import type {ReaderLinkedField, ReaderSelection} from '../util/ReaderNode';
19
- import type {OperationType} from '../util/RelayRuntimeTypes';
19
+ import type {
20
+ UpdatableQuery,
21
+ UpdatableQueryType,
22
+ } from '../util/RelayRuntimeTypes';
20
23
 
21
- const {getRequest} = require('../query/GraphQLTag');
24
+ const {getUpdatableQuery} = require('../query/GraphQLTag');
22
25
  const {getArgumentValues} = require('../store/RelayStoreUtils');
23
26
 
24
27
  const nonUpdatableKeys = ['id', '__id', '__typename', 'js'];
25
28
 
26
- function readUpdatableQuery_EXPERIMENTAL<TQuery: OperationType>(
27
- query: GraphQLTaggedNode,
29
+ function readUpdatableQuery_EXPERIMENTAL<TQuery: UpdatableQueryType>(
30
+ query: UpdatableQuery<TQuery['variables'], TQuery['response']>,
28
31
  variables: TQuery['variables'],
29
32
  proxy: RecordSourceProxy,
30
33
  ): TQuery['response'] {
31
- // TODO assert that the concrete request is an updatable query
32
- const request = getRequest(query);
34
+ const updatableQuery = getUpdatableQuery(query);
33
35
 
34
36
  const updatableProxy = {};
35
37
  updateProxyFromSelections(
36
38
  updatableProxy,
37
39
  proxy.getRoot(),
38
40
  variables,
39
- request.fragment.selections,
41
+ updatableQuery.fragment.selections,
40
42
  proxy,
41
43
  );
42
44
  if (__DEV__) {
@@ -45,7 +47,7 @@ function readUpdatableQuery_EXPERIMENTAL<TQuery: OperationType>(
45
47
  return updatableProxy;
46
48
  }
47
49
 
48
- function updateProxyFromSelections<TQuery: OperationType>(
50
+ function updateProxyFromSelections<TQuery: UpdatableQueryType>(
49
51
  mutableUpdatableProxy: TQuery['response'],
50
52
  recordProxy: RecordProxy,
51
53
  queryVariables: TQuery['variables'],
@@ -161,7 +163,7 @@ function updateProxyFromSelections<TQuery: OperationType>(
161
163
  }
162
164
  }
163
165
 
164
- function createSetterForPluralLinkedField<TQuery: OperationType>(
166
+ function createSetterForPluralLinkedField<TQuery: UpdatableQueryType>(
165
167
  selection: ReaderLinkedField,
166
168
  queryVariables: TQuery['variables'],
167
169
  recordProxy: RecordProxy,
@@ -204,7 +206,7 @@ function createSetterForPluralLinkedField<TQuery: OperationType>(
204
206
  };
205
207
  }
206
208
 
207
- function createSetterForSingularLinkedField<TQuery: OperationType>(
209
+ function createSetterForSingularLinkedField<TQuery: UpdatableQueryType>(
208
210
  selection: ReaderLinkedField,
209
211
  queryVariables: TQuery['variables'],
210
212
  recordProxy: RecordProxy,
@@ -236,7 +238,7 @@ function createSetterForSingularLinkedField<TQuery: OperationType>(
236
238
  };
237
239
  }
238
240
 
239
- function createGetterForPluralLinkedField<TQuery: OperationType>(
241
+ function createGetterForPluralLinkedField<TQuery: UpdatableQueryType>(
240
242
  selection: ReaderLinkedField,
241
243
  queryVariables: TQuery['variables'],
242
244
  recordProxy: RecordProxy,
@@ -278,7 +280,7 @@ function createGetterForPluralLinkedField<TQuery: OperationType>(
278
280
  };
279
281
  }
280
282
 
281
- function createGetterForSingularLinkedField<TQuery: OperationType>(
283
+ function createGetterForSingularLinkedField<TQuery: UpdatableQueryType>(
282
284
  selection: ReaderLinkedField,
283
285
  queryVariables: TQuery['variables'],
284
286
  recordProxy: RecordProxy,
@@ -120,7 +120,7 @@ export type SubscribeFunction = (
120
120
  ) => RelayObservable<GraphQLResponse>;
121
121
 
122
122
  export type Uploadable = File | Blob;
123
- export type UploadableMap = interface {[key: string]: Uploadable};
123
+ export type UploadableMap = {[key: string]: Uploadable};
124
124
 
125
125
  /**
126
126
  * React Flight tree created on the server.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "relay-runtime",
3
3
  "description": "A core runtime for building GraphQL-driven applications.",
4
- "version": "13.0.3",
4
+ "version": "13.2.0",
5
5
  "keywords": [
6
6
  "graphql",
7
7
  "relay"
@@ -18,7 +18,10 @@ import type {
18
18
  ReaderPaginationFragment,
19
19
  ReaderRefetchableFragment,
20
20
  } from '../util/ReaderNode';
21
- import type {ConcreteRequest} from '../util/RelayConcreteNode';
21
+ import type {
22
+ ConcreteRequest,
23
+ ConcreteUpdatableQuery,
24
+ } from '../util/RelayConcreteNode';
22
25
 
23
26
  const RelayConcreteNode = require('../util/RelayConcreteNode');
24
27
  const invariant = require('invariant');
@@ -29,9 +32,14 @@ export type GraphQLTaggedNode =
29
32
  | ReaderFragment
30
33
  | ReaderInlineDataFragment
31
34
  | ConcreteRequest
35
+ | ConcreteUpdatableQuery
32
36
  | {
33
37
  // This is this case when we `require()` a generated ES6 module
34
- default: ReaderFragment | ReaderInlineDataFragment | ConcreteRequest,
38
+ default:
39
+ | ReaderFragment
40
+ | ReaderInlineDataFragment
41
+ | ConcreteRequest
42
+ | ConcreteUpdatableQuery,
35
43
  ...
36
44
  };
37
45
 
@@ -51,7 +59,11 @@ function graphql(strings: Array<string>): any {
51
59
 
52
60
  function getNode(
53
61
  taggedNode: GraphQLTaggedNode,
54
- ): ReaderFragment | ReaderInlineDataFragment | ConcreteRequest {
62
+ ):
63
+ | ReaderFragment
64
+ | ReaderInlineDataFragment
65
+ | ConcreteRequest
66
+ | ConcreteUpdatableQuery {
55
67
  let node = taggedNode;
56
68
  if (typeof node === 'function') {
57
69
  node = (node(): ReaderFragment | ConcreteRequest);
@@ -85,6 +97,15 @@ function isRequest(node: GraphQLTaggedNode): boolean {
85
97
  );
86
98
  }
87
99
 
100
+ function isUpdatableQuery(node: GraphQLTaggedNode): boolean {
101
+ const updatableQuery = getNode(node);
102
+ return (
103
+ typeof updatableQuery === 'object' &&
104
+ updatableQuery !== null &&
105
+ updatableQuery.kind === RelayConcreteNode.UPDATABLE_QUERY
106
+ );
107
+ }
108
+
88
109
  function isInlineDataFragment(node: GraphQLTaggedNode): boolean {
89
110
  const fragment = getNode(node);
90
111
  return (
@@ -142,6 +163,18 @@ function getRequest(taggedNode: GraphQLTaggedNode): ConcreteRequest {
142
163
  return (request: any);
143
164
  }
144
165
 
166
+ function getUpdatableQuery(
167
+ taggedNode: GraphQLTaggedNode,
168
+ ): ConcreteUpdatableQuery {
169
+ const updatableQuery = getNode(taggedNode);
170
+ invariant(
171
+ isUpdatableQuery(updatableQuery),
172
+ 'GraphQLTag: Expected a request, got `%s`.',
173
+ JSON.stringify(updatableQuery),
174
+ );
175
+ return (updatableQuery: any);
176
+ }
177
+
145
178
  function getInlineDataFragment(
146
179
  taggedNode: GraphQLTaggedNode,
147
180
  ): ReaderInlineDataFragment {
@@ -160,9 +193,11 @@ module.exports = {
160
193
  getPaginationFragment,
161
194
  getRefetchableFragment,
162
195
  getRequest,
196
+ getUpdatableQuery,
163
197
  getInlineDataFragment,
164
198
  graphql,
165
199
  isFragment,
166
200
  isRequest,
201
+ isUpdatableQuery,
167
202
  isInlineDataFragment,
168
203
  };
@@ -30,7 +30,7 @@ const RelayObservable = require('../network/RelayObservable');
30
30
  const {
31
31
  createOperationDescriptor,
32
32
  } = require('../store/RelayModernOperationDescriptor');
33
- const reportMissingRequiredFields = require('../util/reportMissingRequiredFields');
33
+ const handlePotentialSnapshotErrors = require('../util/handlePotentialSnapshotErrors');
34
34
  const fetchQueryInternal = require('./fetchQueryInternal');
35
35
  const {getRequest} = require('./GraphQLTag');
36
36
  const invariant = require('invariant');
@@ -138,9 +138,11 @@ function fetchQuery<TVariables: Variables, TData, TRawResponse>(
138
138
  const fetchPolicy = options?.fetchPolicy ?? 'network-only';
139
139
 
140
140
  function readData(snapshot: Snapshot): TData {
141
- if (snapshot.missingRequiredFields != null) {
142
- reportMissingRequiredFields(environment, snapshot.missingRequiredFields);
143
- }
141
+ handlePotentialSnapshotErrors(
142
+ environment,
143
+ snapshot.missingRequiredFields,
144
+ snapshot.relayResolverErrors,
145
+ );
144
146
  /* $FlowFixMe[incompatible-return] we assume readData returns the right
145
147
  * data just having written it from network or checked availability. */
146
148
  return snapshot.data;