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.
- package/handlers/RelayDefaultHandlerProvider.js.flow +41 -0
- package/handlers/connection/ConnectionHandler.js.flow +549 -0
- package/handlers/connection/ConnectionInterface.js.flow +92 -0
- package/handlers/connection/MutationHandlers.js.flow +88 -0
- package/index.js +1 -1
- package/index.js.flow +320 -0
- package/lib/handlers/RelayDefaultHandlerProvider.js +13 -2
- package/lib/handlers/connection/{RelayConnectionHandler.js → ConnectionHandler.js} +33 -35
- package/lib/handlers/connection/{RelayConnectionInterface.js → ConnectionInterface.js} +2 -2
- package/lib/handlers/connection/MutationHandlers.js +86 -0
- package/lib/index.js +15 -19
- package/lib/mutations/RelayDeclarativeMutationConfig.js +29 -52
- package/lib/mutations/RelayRecordProxy.js +1 -3
- package/lib/mutations/RelayRecordSourceMutator.js +2 -9
- package/lib/mutations/RelayRecordSourceProxy.js +2 -4
- package/lib/mutations/RelayRecordSourceSelectorProxy.js +1 -13
- package/lib/mutations/commitMutation.js +13 -3
- package/lib/mutations/validateMutation.js +16 -9
- package/lib/network/RelayObservable.js +9 -9
- package/lib/network/RelayQueryResponseCache.js +8 -6
- package/lib/query/PreloadableQueryRegistry.js +70 -0
- package/lib/query/fetchQueryInternal.js +31 -23
- package/lib/store/DataChecker.js +122 -110
- package/lib/store/RelayConcreteVariables.js +6 -2
- package/lib/store/RelayModernEnvironment.js +121 -67
- package/lib/store/RelayModernFragmentSpecResolver.js +12 -16
- package/lib/store/RelayModernQueryExecutor.js +389 -314
- package/lib/store/RelayModernRecord.js +14 -9
- package/lib/store/RelayModernSelector.js +7 -3
- package/lib/store/RelayModernStore.js +289 -484
- package/lib/store/RelayOperationTracker.js +35 -78
- package/lib/store/RelayOptimisticRecordSource.js +7 -5
- package/lib/store/RelayPublishQueue.js +6 -33
- package/lib/store/RelayReader.js +113 -45
- package/lib/store/RelayRecordSource.js +2 -9
- package/lib/store/RelayRecordSourceMapImpl.js +13 -18
- package/lib/store/RelayReferenceMarker.js +40 -60
- package/lib/store/RelayResponseNormalizer.js +158 -193
- package/lib/store/RelayStoreUtils.js +1 -0
- package/lib/store/StoreInspector.js +8 -8
- package/lib/store/TypeID.js +28 -0
- package/lib/store/cloneRelayScalarHandleSourceField.js +44 -0
- package/lib/store/normalizeRelayPayload.js +6 -2
- package/lib/store/readInlineData.js +1 -1
- package/lib/subscription/requestSubscription.js +5 -3
- package/lib/util/RelayConcreteNode.js +9 -6
- package/lib/util/RelayError.js +39 -9
- package/lib/util/RelayFeatureFlags.js +2 -5
- package/lib/util/RelayReplaySubject.js +3 -3
- package/lib/util/createPayloadFor3DField.js +7 -2
- package/lib/util/getRequestIdentifier.js +2 -2
- package/lib/util/recycleNodesInto.js +2 -6
- package/mutations/RelayDeclarativeMutationConfig.js.flow +380 -0
- package/mutations/RelayRecordProxy.js.flow +165 -0
- package/mutations/RelayRecordSourceMutator.js.flow +238 -0
- package/mutations/RelayRecordSourceProxy.js.flow +164 -0
- package/mutations/RelayRecordSourceSelectorProxy.js.flow +119 -0
- package/mutations/applyOptimisticMutation.js.flow +76 -0
- package/mutations/commitLocalUpdate.js.flow +24 -0
- package/mutations/commitMutation.js.flow +182 -0
- package/mutations/validateMutation.js.flow +213 -0
- package/network/ConvertToExecuteFunction.js.flow +49 -0
- package/network/RelayNetwork.js.flow +84 -0
- package/network/RelayNetworkTypes.js.flow +123 -0
- package/network/RelayObservable.js.flow +634 -0
- package/network/RelayQueryResponseCache.js.flow +111 -0
- package/package.json +1 -1
- package/query/GraphQLTag.js.flow +166 -0
- package/query/PreloadableQueryRegistry.js.flow +65 -0
- package/query/fetchQuery.js.flow +47 -0
- package/query/fetchQueryInternal.js.flow +348 -0
- package/relay-runtime.js +2 -2
- package/relay-runtime.min.js +2 -2
- package/store/ClientID.js.flow +43 -0
- package/store/DataChecker.js.flow +502 -0
- package/store/RelayConcreteVariables.js.flow +96 -0
- package/store/RelayModernEnvironment.js.flow +551 -0
- package/store/RelayModernFragmentSpecResolver.js.flow +426 -0
- package/store/RelayModernOperationDescriptor.js.flow +88 -0
- package/store/RelayModernQueryExecutor.js.flow +1321 -0
- package/store/RelayModernRecord.js.flow +403 -0
- package/store/RelayModernSelector.js.flow +455 -0
- package/store/RelayModernStore.js.flow +842 -0
- package/store/RelayOperationTracker.js.flow +164 -0
- package/store/RelayOptimisticRecordSource.js.flow +119 -0
- package/store/RelayPublishQueue.js.flow +401 -0
- package/store/RelayReader.js.flow +473 -0
- package/store/RelayRecordSource.js.flow +29 -0
- package/store/RelayRecordSourceMapImpl.js.flow +87 -0
- package/store/RelayRecordState.js.flow +37 -0
- package/store/RelayReferenceMarker.js.flow +257 -0
- package/store/RelayResponseNormalizer.js.flow +680 -0
- package/store/RelayStoreTypes.js.flow +899 -0
- package/store/RelayStoreUtils.js.flow +219 -0
- package/store/StoreInspector.js.flow +171 -0
- package/store/TypeID.js.flow +28 -0
- package/store/ViewerPattern.js.flow +26 -0
- package/store/cloneRelayHandleSourceField.js.flow +66 -0
- package/store/cloneRelayScalarHandleSourceField.js.flow +62 -0
- package/store/createFragmentSpecResolver.js.flow +55 -0
- package/store/createRelayContext.js.flow +44 -0
- package/store/defaultGetDataID.js.flow +27 -0
- package/store/hasOverlappingIDs.js.flow +34 -0
- package/store/isRelayModernEnvironment.js.flow +27 -0
- package/store/normalizeRelayPayload.js.flow +51 -0
- package/store/readInlineData.js.flow +75 -0
- package/subscription/requestSubscription.js.flow +100 -0
- package/util/JSResourceTypes.flow.js.flow +20 -0
- package/util/NormalizationNode.js.flow +198 -0
- package/util/ReaderNode.js.flow +208 -0
- package/util/RelayConcreteNode.js.flow +93 -0
- package/util/RelayDefaultHandleKey.js.flow +17 -0
- package/util/RelayError.js.flow +62 -0
- package/util/RelayFeatureFlags.js.flow +30 -0
- package/util/RelayProfiler.js.flow +284 -0
- package/util/RelayReplaySubject.js.flow +135 -0
- package/util/RelayRuntimeTypes.js.flow +72 -0
- package/util/createPayloadFor3DField.js.flow +43 -0
- package/util/deepFreeze.js.flow +36 -0
- package/util/generateID.js.flow +21 -0
- package/util/getFragmentIdentifier.js.flow +52 -0
- package/util/getRelayHandleKey.js.flow +41 -0
- package/util/getRequestIdentifier.js.flow +42 -0
- package/util/isPromise.js.flow +21 -0
- package/util/isScalarAndEqual.js.flow +26 -0
- package/util/recycleNodesInto.js.flow +76 -0
- package/util/resolveImmediate.js.flow +30 -0
- package/util/stableCopy.js.flow +35 -0
- package/lib/handlers/RelayDefaultMissingFieldHandlers.js +0 -26
- package/lib/handlers/getRelayDefaultMissingFieldHandlers.js +0 -36
- package/lib/query/RelayModernGraphQLTag.js +0 -104
- package/lib/store/RelayConnection.js +0 -37
- package/lib/store/RelayConnectionResolver.js +0 -178
- package/lib/store/RelayRecordSourceObjectImpl.js +0 -79
- package/lib/util/getFragmentSpecIdentifier.js +0 -27
|
@@ -0,0 +1,219 @@
|
|
|
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
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// flowlint ambiguous-object-type:error
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const RelayConcreteNode = require('../util/RelayConcreteNode');
|
|
16
|
+
|
|
17
|
+
const getRelayHandleKey = require('../util/getRelayHandleKey');
|
|
18
|
+
const invariant = require('invariant');
|
|
19
|
+
const stableCopy = require('../util/stableCopy');
|
|
20
|
+
|
|
21
|
+
import type {
|
|
22
|
+
NormalizationHandle,
|
|
23
|
+
NormalizationArgument,
|
|
24
|
+
NormalizationField,
|
|
25
|
+
} from '../util/NormalizationNode';
|
|
26
|
+
import type {ReaderArgument, ReaderField} from '../util/ReaderNode';
|
|
27
|
+
import type {Variables} from '../util/RelayRuntimeTypes';
|
|
28
|
+
|
|
29
|
+
export type Arguments = {+[string]: mixed, ...};
|
|
30
|
+
|
|
31
|
+
const {VARIABLE, LITERAL, OBJECT_VALUE, LIST_VALUE} = RelayConcreteNode;
|
|
32
|
+
|
|
33
|
+
const MODULE_COMPONENT_KEY_PREFIX = '__module_component_';
|
|
34
|
+
const MODULE_OPERATION_KEY_PREFIX = '__module_operation_';
|
|
35
|
+
|
|
36
|
+
function getArgumentValue(
|
|
37
|
+
arg: NormalizationArgument | ReaderArgument,
|
|
38
|
+
variables: Variables,
|
|
39
|
+
): mixed {
|
|
40
|
+
if (arg.kind === VARIABLE) {
|
|
41
|
+
// Variables are provided at runtime and are not guaranteed to be stable.
|
|
42
|
+
return getStableVariableValue(arg.variableName, variables);
|
|
43
|
+
} else if (arg.kind === LITERAL) {
|
|
44
|
+
// The Relay compiler generates stable ConcreteArgument values.
|
|
45
|
+
return arg.value;
|
|
46
|
+
} else if (arg.kind === OBJECT_VALUE) {
|
|
47
|
+
const value = {};
|
|
48
|
+
arg.fields.forEach(field => {
|
|
49
|
+
value[field.name] = getArgumentValue(field, variables);
|
|
50
|
+
});
|
|
51
|
+
return value;
|
|
52
|
+
} else if (arg.kind === LIST_VALUE) {
|
|
53
|
+
const value = [];
|
|
54
|
+
arg.items.forEach(item => {
|
|
55
|
+
item != null ? value.push(getArgumentValue(item, variables)) : null;
|
|
56
|
+
});
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Returns the values of field/fragment arguments as an object keyed by argument
|
|
63
|
+
* names. Guaranteed to return a result with stable ordered nested values.
|
|
64
|
+
*/
|
|
65
|
+
function getArgumentValues(
|
|
66
|
+
args: $ReadOnlyArray<NormalizationArgument | ReaderArgument>,
|
|
67
|
+
variables: Variables,
|
|
68
|
+
): Arguments {
|
|
69
|
+
const values = {};
|
|
70
|
+
args.forEach(arg => {
|
|
71
|
+
values[arg.name] = getArgumentValue(arg, variables);
|
|
72
|
+
});
|
|
73
|
+
return values;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Given a handle field and variable values, returns a key that can be used to
|
|
78
|
+
* uniquely identify the combination of the handle name and argument values.
|
|
79
|
+
*
|
|
80
|
+
* Note: the word "storage" here refers to the fact this key is primarily used
|
|
81
|
+
* when writing the results of a key in a normalized graph or "store". This
|
|
82
|
+
* name was used in previous implementations of Relay internals and is also
|
|
83
|
+
* used here for consistency.
|
|
84
|
+
*/
|
|
85
|
+
function getHandleStorageKey(
|
|
86
|
+
handleField: NormalizationHandle,
|
|
87
|
+
variables: Variables,
|
|
88
|
+
): string {
|
|
89
|
+
const {dynamicKey, handle, key, name, args, filters} = handleField;
|
|
90
|
+
const handleName = getRelayHandleKey(handle, key, name);
|
|
91
|
+
let filterArgs = null;
|
|
92
|
+
if (args && filters && args.length !== 0 && filters.length !== 0) {
|
|
93
|
+
filterArgs = args.filter(arg => filters.indexOf(arg.name) > -1);
|
|
94
|
+
}
|
|
95
|
+
if (dynamicKey) {
|
|
96
|
+
// "Sort" the arguments by argument name: this is done by the compiler for
|
|
97
|
+
// user-supplied arguments but the dynamic argument must also be in sorted
|
|
98
|
+
// order. Note that dynamic key argument name is double-underscore-
|
|
99
|
+
// -prefixed, and a double-underscore prefix is disallowed for user-supplied
|
|
100
|
+
// argument names, so there's no need to actually sort.
|
|
101
|
+
filterArgs =
|
|
102
|
+
filterArgs != null ? [dynamicKey, ...filterArgs] : [dynamicKey];
|
|
103
|
+
}
|
|
104
|
+
if (filterArgs === null) {
|
|
105
|
+
return handleName;
|
|
106
|
+
} else {
|
|
107
|
+
return formatStorageKey(
|
|
108
|
+
handleName,
|
|
109
|
+
getArgumentValues(filterArgs, variables),
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Given a field and variable values, returns a key that can be used to
|
|
116
|
+
* uniquely identify the combination of the field name and argument values.
|
|
117
|
+
*
|
|
118
|
+
* Note: the word "storage" here refers to the fact this key is primarily used
|
|
119
|
+
* when writing the results of a key in a normalized graph or "store". This
|
|
120
|
+
* name was used in previous implementations of Relay internals and is also
|
|
121
|
+
* used here for consistency.
|
|
122
|
+
*/
|
|
123
|
+
function getStorageKey(
|
|
124
|
+
field: NormalizationField | NormalizationHandle | ReaderField,
|
|
125
|
+
variables: Variables,
|
|
126
|
+
): string {
|
|
127
|
+
if (field.storageKey) {
|
|
128
|
+
// TODO T23663664: Handle nodes do not yet define a static storageKey.
|
|
129
|
+
return (field: $FlowFixMe).storageKey;
|
|
130
|
+
}
|
|
131
|
+
const {args, name} = field;
|
|
132
|
+
return args && args.length !== 0
|
|
133
|
+
? formatStorageKey(name, getArgumentValues(args, variables))
|
|
134
|
+
: name;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Given a `name` (eg. "foo") and an object representing argument values
|
|
139
|
+
* (eg. `{orberBy: "name", first: 10}`) returns a unique storage key
|
|
140
|
+
* (ie. `foo{"first":10,"orderBy":"name"}`).
|
|
141
|
+
*
|
|
142
|
+
* This differs from getStorageKey which requires a ConcreteNode where arguments
|
|
143
|
+
* are assumed to already be sorted into a stable order.
|
|
144
|
+
*/
|
|
145
|
+
function getStableStorageKey(name: string, args: ?Arguments): string {
|
|
146
|
+
return formatStorageKey(name, stableCopy(args));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Given a name and argument values, format a storage key.
|
|
151
|
+
*
|
|
152
|
+
* Arguments and the values within them are expected to be ordered in a stable
|
|
153
|
+
* alphabetical ordering.
|
|
154
|
+
*/
|
|
155
|
+
function formatStorageKey(name: string, argValues: ?Arguments): string {
|
|
156
|
+
if (!argValues) {
|
|
157
|
+
return name;
|
|
158
|
+
}
|
|
159
|
+
const values = [];
|
|
160
|
+
for (const argName in argValues) {
|
|
161
|
+
if (argValues.hasOwnProperty(argName)) {
|
|
162
|
+
const value = argValues[argName];
|
|
163
|
+
if (value != null) {
|
|
164
|
+
values.push(argName + ':' + (JSON.stringify(value) ?? 'undefined'));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return values.length === 0 ? name : name + `(${values.join(',')})`;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Given Variables and a variable name, return a variable value with
|
|
173
|
+
* all values in a stable order.
|
|
174
|
+
*/
|
|
175
|
+
function getStableVariableValue(name: string, variables: Variables): mixed {
|
|
176
|
+
invariant(
|
|
177
|
+
variables.hasOwnProperty(name),
|
|
178
|
+
'getVariableValue(): Undefined variable `%s`.',
|
|
179
|
+
name,
|
|
180
|
+
);
|
|
181
|
+
return stableCopy(variables[name]);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function getModuleComponentKey(documentName: string): string {
|
|
185
|
+
return `${MODULE_COMPONENT_KEY_PREFIX}${documentName}`;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function getModuleOperationKey(documentName: string): string {
|
|
189
|
+
return `${MODULE_OPERATION_KEY_PREFIX}${documentName}`;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Constants shared by all implementations of RecordSource/MutableRecordSource/etc.
|
|
194
|
+
*/
|
|
195
|
+
const RelayStoreUtils = {
|
|
196
|
+
FRAGMENTS_KEY: '__fragments',
|
|
197
|
+
FRAGMENT_OWNER_KEY: '__fragmentOwner',
|
|
198
|
+
FRAGMENT_PROP_NAME_KEY: '__fragmentPropName',
|
|
199
|
+
MODULE_COMPONENT_KEY: '__module_component', // alias returned by Reader
|
|
200
|
+
ID_KEY: '__id',
|
|
201
|
+
REF_KEY: '__ref',
|
|
202
|
+
REFS_KEY: '__refs',
|
|
203
|
+
ROOT_ID: 'client:root',
|
|
204
|
+
ROOT_TYPE: '__Root',
|
|
205
|
+
TYPENAME_KEY: '__typename',
|
|
206
|
+
INVALIDATED_AT_KEY: '__invalidated_at',
|
|
207
|
+
IS_WITHIN_UNMATCHED_TYPE_REFINEMENT: '__isWithinUnmatchedTypeRefinement',
|
|
208
|
+
|
|
209
|
+
formatStorageKey,
|
|
210
|
+
getArgumentValue,
|
|
211
|
+
getArgumentValues,
|
|
212
|
+
getHandleStorageKey,
|
|
213
|
+
getStorageKey,
|
|
214
|
+
getStableStorageKey,
|
|
215
|
+
getModuleComponentKey,
|
|
216
|
+
getModuleOperationKey,
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
module.exports = RelayStoreUtils;
|
|
@@ -0,0 +1,171 @@
|
|
|
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
|
+
* @emails oncall+relay
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// flowlint ambiguous-object-type:error
|
|
13
|
+
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
import type {IEnvironment, RecordSource} from '../store/RelayStoreTypes';
|
|
17
|
+
|
|
18
|
+
type InspectFn = (environment: IEnvironment, dataID?: ?string) => mixed;
|
|
19
|
+
|
|
20
|
+
let inspect: InspectFn = () => {};
|
|
21
|
+
|
|
22
|
+
if (__DEV__) {
|
|
23
|
+
let formattersInstalled = false;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Installs a Chrome Developer Tools custom formatter for Relay proxy objects
|
|
27
|
+
* returned by StoreInspector.inspect.
|
|
28
|
+
*
|
|
29
|
+
* bit.ly/object-formatters
|
|
30
|
+
*/
|
|
31
|
+
const installDevtoolFormatters = () => {
|
|
32
|
+
if (formattersInstalled) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
formattersInstalled = true;
|
|
36
|
+
if (window.devtoolsFormatters == null) {
|
|
37
|
+
window.devtoolsFormatters = [];
|
|
38
|
+
}
|
|
39
|
+
if (!Array.isArray(window.devtoolsFormatters)) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// eslint-disable-next-line no-console
|
|
43
|
+
console.info(
|
|
44
|
+
'Make sure to select "Enable custom formatters" in the Chrome ' +
|
|
45
|
+
'Developer Tools settings, tab "Preferences" under the "Console" ' +
|
|
46
|
+
'section.',
|
|
47
|
+
);
|
|
48
|
+
window.devtoolsFormatters.push(...createFormatters());
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const createFormatters = () => {
|
|
52
|
+
const listStyle = {
|
|
53
|
+
style:
|
|
54
|
+
'list-style-type: none; padding: 0; margin: 0 0 0 12px; font-style: normal',
|
|
55
|
+
};
|
|
56
|
+
const keyStyle = {style: 'rgb(136, 19, 145)'};
|
|
57
|
+
const nullStyle = {style: 'color: #777'};
|
|
58
|
+
|
|
59
|
+
const reference = (object, config) => {
|
|
60
|
+
return object == null
|
|
61
|
+
? ['span', nullStyle, 'undefined']
|
|
62
|
+
: ['object', {object, config}];
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const renderRecordHeader = record => {
|
|
66
|
+
return [
|
|
67
|
+
'span',
|
|
68
|
+
{style: 'font-style: italic'},
|
|
69
|
+
record.__typename,
|
|
70
|
+
['span', nullStyle, ' {id: "', record.__id, '", …}'],
|
|
71
|
+
];
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const isRecord = o => o != null && typeof o.__id === 'string';
|
|
75
|
+
|
|
76
|
+
class RecordEntry {
|
|
77
|
+
+key: string;
|
|
78
|
+
+value: mixed;
|
|
79
|
+
constructor(key: string, value: mixed) {
|
|
80
|
+
this.key = key;
|
|
81
|
+
this.value = value;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const renderRecordEntries = record => {
|
|
86
|
+
const children = Object.keys(record).map(key => {
|
|
87
|
+
return [
|
|
88
|
+
'li',
|
|
89
|
+
{},
|
|
90
|
+
['object', {object: new RecordEntry(key, record[key])}],
|
|
91
|
+
];
|
|
92
|
+
});
|
|
93
|
+
return ['ol', listStyle, ...children];
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const recordFormatter = {
|
|
97
|
+
header(obj) {
|
|
98
|
+
if (!isRecord(obj)) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
return renderRecordHeader(obj);
|
|
102
|
+
},
|
|
103
|
+
hasBody(obj) {
|
|
104
|
+
return true;
|
|
105
|
+
},
|
|
106
|
+
body(obj) {
|
|
107
|
+
return renderRecordEntries(obj);
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const recordEntryFormatter = {
|
|
112
|
+
header(obj) {
|
|
113
|
+
if (obj instanceof RecordEntry) {
|
|
114
|
+
const value = isRecord(obj.value)
|
|
115
|
+
? renderRecordHeader(obj.value)
|
|
116
|
+
: reference(obj.value);
|
|
117
|
+
return ['span', keyStyle, obj.key, ': ', value];
|
|
118
|
+
}
|
|
119
|
+
return null;
|
|
120
|
+
},
|
|
121
|
+
hasBody(obj) {
|
|
122
|
+
return isRecord(obj.value);
|
|
123
|
+
},
|
|
124
|
+
body(obj) {
|
|
125
|
+
return renderRecordEntries(obj.value);
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
return [recordFormatter, recordEntryFormatter];
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const getWrappedRecord = (source: RecordSource, dataID: string) => {
|
|
133
|
+
const record = source.get(dataID);
|
|
134
|
+
if (record == null) {
|
|
135
|
+
return record;
|
|
136
|
+
}
|
|
137
|
+
return new Proxy(
|
|
138
|
+
{...record},
|
|
139
|
+
{
|
|
140
|
+
get(target, prop) {
|
|
141
|
+
const value = target[prop];
|
|
142
|
+
if (value == null) {
|
|
143
|
+
return value;
|
|
144
|
+
}
|
|
145
|
+
if (typeof value === 'object') {
|
|
146
|
+
if (typeof value.__ref === 'string') {
|
|
147
|
+
return getWrappedRecord(source, value.__ref);
|
|
148
|
+
}
|
|
149
|
+
if (Array.isArray(value.__refs)) {
|
|
150
|
+
// $FlowFixMe[incompatible-call]
|
|
151
|
+
return value.__refs.map(ref => getWrappedRecord(source, ref));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return value;
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
);
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
inspect = (environment: IEnvironment, dataID: ?string) => {
|
|
161
|
+
installDevtoolFormatters();
|
|
162
|
+
return getWrappedRecord(
|
|
163
|
+
environment.getStore().getSource(),
|
|
164
|
+
dataID ?? 'client:root',
|
|
165
|
+
);
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
module.exports = {
|
|
170
|
+
inspect,
|
|
171
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// flowlint ambiguous-object-type:error
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
import type {DataID} from '../util/RelayRuntimeTypes';
|
|
16
|
+
|
|
17
|
+
const PREFIX = 'client:__type:';
|
|
18
|
+
const TYPE_SCHEMA_TYPE = '__TypeSchema';
|
|
19
|
+
|
|
20
|
+
function generateTypeID(typeName: string): DataID {
|
|
21
|
+
return PREFIX + typeName;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function isTypeID(id: DataID): boolean {
|
|
25
|
+
return id.indexOf(PREFIX) === 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports = {generateTypeID, isTypeID, TYPE_SCHEMA_TYPE};
|
|
@@ -0,0 +1,26 @@
|
|
|
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 {generateClientID} = require('./ClientID');
|
|
16
|
+
const {ROOT_ID} = require('./RelayStoreUtils');
|
|
17
|
+
|
|
18
|
+
import type {DataID} from 'relay-runtime/util/RelayRuntimeTypes';
|
|
19
|
+
|
|
20
|
+
const VIEWER_ID: DataID = generateClientID(ROOT_ID, 'viewer');
|
|
21
|
+
const VIEWER_TYPE = 'Viewer';
|
|
22
|
+
|
|
23
|
+
module.exports = {
|
|
24
|
+
VIEWER_ID,
|
|
25
|
+
VIEWER_TYPE,
|
|
26
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
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
|
+
|
|
18
|
+
const {LINKED_FIELD} = require('../util/RelayConcreteNode');
|
|
19
|
+
const {getHandleStorageKey} = require('./RelayStoreUtils');
|
|
20
|
+
|
|
21
|
+
import type {
|
|
22
|
+
NormalizationLinkedField,
|
|
23
|
+
NormalizationSelection,
|
|
24
|
+
} from '../util/NormalizationNode';
|
|
25
|
+
import type {NormalizationLinkedHandle} from '../util/NormalizationNode';
|
|
26
|
+
import type {Variables} from '../util/RelayRuntimeTypes';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @private
|
|
30
|
+
*
|
|
31
|
+
* Creates a clone of the supplied `handleField` by finding the original linked
|
|
32
|
+
* field (on which the handle was declared) among the sibling `selections`, and
|
|
33
|
+
* copying its selections into the clone.
|
|
34
|
+
*/
|
|
35
|
+
function cloneRelayHandleSourceField(
|
|
36
|
+
handleField: NormalizationLinkedHandle,
|
|
37
|
+
selections: $ReadOnlyArray<NormalizationSelection>,
|
|
38
|
+
variables: Variables,
|
|
39
|
+
): NormalizationLinkedField {
|
|
40
|
+
const sourceField = selections.find(
|
|
41
|
+
source =>
|
|
42
|
+
source.kind === LINKED_FIELD &&
|
|
43
|
+
source.name === handleField.name &&
|
|
44
|
+
source.alias === handleField.alias &&
|
|
45
|
+
areEqual(source.args, handleField.args),
|
|
46
|
+
);
|
|
47
|
+
invariant(
|
|
48
|
+
sourceField && sourceField.kind === LINKED_FIELD,
|
|
49
|
+
'cloneRelayHandleSourceField: Expected a corresponding source field for ' +
|
|
50
|
+
'handle `%s`.',
|
|
51
|
+
handleField.handle,
|
|
52
|
+
);
|
|
53
|
+
const handleKey = getHandleStorageKey(handleField, variables);
|
|
54
|
+
return {
|
|
55
|
+
kind: 'LinkedField',
|
|
56
|
+
alias: sourceField.alias,
|
|
57
|
+
name: handleKey,
|
|
58
|
+
storageKey: handleKey,
|
|
59
|
+
args: null,
|
|
60
|
+
concreteType: sourceField.concreteType,
|
|
61
|
+
plural: sourceField.plural,
|
|
62
|
+
selections: sourceField.selections,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = cloneRelayHandleSourceField;
|
|
@@ -0,0 +1,62 @@
|
|
|
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
|
+
|
|
18
|
+
const {SCALAR_FIELD} = require('../util/RelayConcreteNode');
|
|
19
|
+
const {getHandleStorageKey} = require('./RelayStoreUtils');
|
|
20
|
+
|
|
21
|
+
import type {
|
|
22
|
+
NormalizationScalarField,
|
|
23
|
+
NormalizationSelection,
|
|
24
|
+
} from '../util/NormalizationNode';
|
|
25
|
+
import type {NormalizationScalarHandle} from '../util/NormalizationNode';
|
|
26
|
+
import type {Variables} from '../util/RelayRuntimeTypes';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @private
|
|
30
|
+
*
|
|
31
|
+
* Creates a clone of the supplied `handleField` by finding the original scalar
|
|
32
|
+
* field (on which the handle was declared) among the sibling `selections`.
|
|
33
|
+
*/
|
|
34
|
+
function cloneRelayScalarHandleSourceField(
|
|
35
|
+
handleField: NormalizationScalarHandle,
|
|
36
|
+
selections: $ReadOnlyArray<NormalizationSelection>,
|
|
37
|
+
variables: Variables,
|
|
38
|
+
): NormalizationScalarField {
|
|
39
|
+
const sourceField = selections.find(
|
|
40
|
+
source =>
|
|
41
|
+
source.kind === SCALAR_FIELD &&
|
|
42
|
+
source.name === handleField.name &&
|
|
43
|
+
source.alias === handleField.alias &&
|
|
44
|
+
areEqual(source.args, handleField.args),
|
|
45
|
+
);
|
|
46
|
+
invariant(
|
|
47
|
+
sourceField && sourceField.kind === SCALAR_FIELD,
|
|
48
|
+
'cloneRelayScalarHandleSourceField: Expected a corresponding source field for ' +
|
|
49
|
+
'handle `%s`.',
|
|
50
|
+
handleField.handle,
|
|
51
|
+
);
|
|
52
|
+
const handleKey = getHandleStorageKey(handleField, variables);
|
|
53
|
+
return {
|
|
54
|
+
kind: 'ScalarField',
|
|
55
|
+
alias: sourceField.alias,
|
|
56
|
+
name: handleKey,
|
|
57
|
+
storageKey: handleKey,
|
|
58
|
+
args: null,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = cloneRelayScalarHandleSourceField;
|
|
@@ -0,0 +1,55 @@
|
|
|
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 RelayModernFragmentSpecResolver = require('./RelayModernFragmentSpecResolver');
|
|
16
|
+
|
|
17
|
+
const warning = require('warning');
|
|
18
|
+
|
|
19
|
+
import type {
|
|
20
|
+
FragmentMap,
|
|
21
|
+
FragmentSpecResolver,
|
|
22
|
+
Props,
|
|
23
|
+
RelayContext,
|
|
24
|
+
} from './RelayStoreTypes';
|
|
25
|
+
|
|
26
|
+
function createFragmentSpecResolver(
|
|
27
|
+
context: RelayContext,
|
|
28
|
+
containerName: string,
|
|
29
|
+
fragments: FragmentMap,
|
|
30
|
+
props: Props,
|
|
31
|
+
callback?: () => void,
|
|
32
|
+
): FragmentSpecResolver {
|
|
33
|
+
if (__DEV__) {
|
|
34
|
+
const fragmentNames = Object.keys(fragments);
|
|
35
|
+
fragmentNames.forEach(fragmentName => {
|
|
36
|
+
const propValue = props[fragmentName];
|
|
37
|
+
warning(
|
|
38
|
+
propValue !== undefined,
|
|
39
|
+
'createFragmentSpecResolver: Expected prop `%s` to be supplied to `%s`, but ' +
|
|
40
|
+
'got `undefined`. Pass an explicit `null` if this is intentional.',
|
|
41
|
+
fragmentName,
|
|
42
|
+
containerName,
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return new RelayModernFragmentSpecResolver(
|
|
48
|
+
context,
|
|
49
|
+
fragments,
|
|
50
|
+
props,
|
|
51
|
+
callback,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
module.exports = createFragmentSpecResolver;
|
|
@@ -0,0 +1,44 @@
|
|
|
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 invariant = require('invariant');
|
|
16
|
+
|
|
17
|
+
import type {RelayContext} from './RelayStoreTypes.js';
|
|
18
|
+
import typeof {createContext} from 'react';
|
|
19
|
+
|
|
20
|
+
// Ideally, we'd just import the type of the react module, but this causes Flow
|
|
21
|
+
// problems.
|
|
22
|
+
type React = {
|
|
23
|
+
createContext: createContext<RelayContext | null>,
|
|
24
|
+
version: string,
|
|
25
|
+
...
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
let relayContext: ?React$Context<RelayContext | null>;
|
|
29
|
+
let firstReact: ?React;
|
|
30
|
+
|
|
31
|
+
function createRelayContext(react: React): React$Context<RelayContext | null> {
|
|
32
|
+
if (!relayContext) {
|
|
33
|
+
relayContext = react.createContext(null);
|
|
34
|
+
firstReact = react;
|
|
35
|
+
}
|
|
36
|
+
invariant(
|
|
37
|
+
react === firstReact,
|
|
38
|
+
'[createRelayContext]: You passing a different instance of React',
|
|
39
|
+
react.version,
|
|
40
|
+
);
|
|
41
|
+
return relayContext;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = createRelayContext;
|
|
@@ -0,0 +1,27 @@
|
|
|
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 {VIEWER_ID, VIEWER_TYPE} = require('./ViewerPattern');
|
|
16
|
+
|
|
17
|
+
function defaultGetDataID(
|
|
18
|
+
fieldValue: {[string]: mixed, ...},
|
|
19
|
+
typeName: string,
|
|
20
|
+
): mixed {
|
|
21
|
+
if (typeName === VIEWER_TYPE) {
|
|
22
|
+
return fieldValue.id == null ? VIEWER_ID : fieldValue.id;
|
|
23
|
+
}
|
|
24
|
+
return fieldValue.id;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = defaultGetDataID;
|