relay-runtime 9.0.0 → 9.1.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/handlers/RelayDefaultHandlerProvider.js.flow +34 -0
- package/handlers/connection/ConnectionHandler.js.flow +549 -0
- package/handlers/connection/ConnectionInterface.js.flow +92 -0
- package/index.js +1 -1
- package/index.js.flow +314 -0
- package/lib/handlers/connection/ConnectionHandler.js +1 -3
- package/lib/index.js +1 -2
- package/lib/mutations/RelayDeclarativeMutationConfig.js +22 -45
- package/lib/mutations/RelayRecordProxy.js +1 -3
- package/lib/mutations/RelayRecordSourceMutator.js +1 -3
- package/lib/mutations/RelayRecordSourceProxy.js +1 -3
- package/lib/mutations/RelayRecordSourceSelectorProxy.js +1 -3
- package/lib/mutations/commitMutation.js +2 -0
- package/lib/mutations/validateMutation.js +13 -4
- package/lib/network/RelayObservable.js +9 -9
- package/lib/network/RelayQueryResponseCache.js +8 -6
- package/lib/query/fetchQueryInternal.js +1 -8
- package/lib/store/DataChecker.js +23 -51
- package/lib/store/RelayConcreteVariables.js +6 -2
- package/lib/store/RelayModernEnvironment.js +30 -12
- package/lib/store/RelayModernFragmentSpecResolver.js +9 -13
- package/lib/store/RelayModernQueryExecutor.js +73 -37
- package/lib/store/RelayModernRecord.js +14 -9
- package/lib/store/RelayModernStore.js +107 -70
- package/lib/store/RelayOperationTracker.js +35 -78
- package/lib/store/RelayOptimisticRecordSource.js +7 -5
- package/lib/store/RelayPublishQueue.js +1 -3
- package/lib/store/RelayReader.js +1 -3
- package/lib/store/RelayRecordSource.js +1 -3
- package/lib/store/RelayRecordSourceMapImpl.js +13 -18
- package/lib/store/RelayReferenceMarker.js +2 -6
- package/lib/store/RelayResponseNormalizer.js +9 -10
- package/lib/store/StoreInspector.js +7 -5
- package/lib/store/normalizeRelayPayload.js +6 -2
- package/lib/subscription/requestSubscription.js +4 -2
- package/lib/util/RelayFeatureFlags.js +1 -1
- package/lib/util/RelayReplaySubject.js +1 -3
- package/lib/util/createPayloadFor3DField.js +7 -2
- 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 +184 -0
- package/mutations/validateMutation.js.flow +211 -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/fetchQuery.js.flow +47 -0
- package/query/fetchQueryInternal.js.flow +349 -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 +426 -0
- package/store/RelayConcreteVariables.js.flow +96 -0
- package/store/RelayModernEnvironment.js.flow +526 -0
- package/store/RelayModernFragmentSpecResolver.js.flow +426 -0
- package/store/RelayModernOperationDescriptor.js.flow +88 -0
- package/store/RelayModernQueryExecutor.js.flow +1327 -0
- package/store/RelayModernRecord.js.flow +403 -0
- package/store/RelayModernSelector.js.flow +444 -0
- package/store/RelayModernStore.js.flow +757 -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 +376 -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 +236 -0
- package/store/RelayResponseNormalizer.js.flow +556 -0
- package/store/RelayStoreTypes.js.flow +873 -0
- package/store/RelayStoreUtils.js.flow +218 -0
- package/store/StoreInspector.js.flow +173 -0
- package/store/ViewerPattern.js.flow +26 -0
- package/store/cloneRelayHandleSourceField.js.flow +66 -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 +191 -0
- package/util/ReaderNode.js.flow +208 -0
- package/util/RelayConcreteNode.js.flow +80 -0
- package/util/RelayDefaultHandleKey.js.flow +17 -0
- package/util/RelayError.js.flow +33 -0
- package/util/RelayFeatureFlags.js.flow +30 -0
- package/util/RelayProfiler.js.flow +284 -0
- package/util/RelayReplaySubject.js.flow +134 -0
- package/util/RelayRuntimeTypes.js.flow +70 -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 +41 -0
- package/util/isPromise.js.flow +21 -0
- package/util/isScalarAndEqual.js.flow +26 -0
- package/util/recycleNodesInto.js.flow +80 -0
- package/util/resolveImmediate.js.flow +30 -0
- package/util/stableCopy.js.flow +35 -0
|
@@ -0,0 +1,403 @@
|
|
|
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 areEqual = require('areEqual');
|
|
16
|
+
const deepFreeze = require('../util/deepFreeze');
|
|
17
|
+
const invariant = require('invariant');
|
|
18
|
+
const warning = require('warning');
|
|
19
|
+
|
|
20
|
+
const {isClientID} = require('./ClientID');
|
|
21
|
+
const {
|
|
22
|
+
ID_KEY,
|
|
23
|
+
REF_KEY,
|
|
24
|
+
REFS_KEY,
|
|
25
|
+
TYPENAME_KEY,
|
|
26
|
+
INVALIDATED_AT_KEY,
|
|
27
|
+
ROOT_ID,
|
|
28
|
+
} = require('./RelayStoreUtils');
|
|
29
|
+
|
|
30
|
+
import type {DataID} from '../util/RelayRuntimeTypes';
|
|
31
|
+
import type {Record} from './RelayStoreTypes';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @public
|
|
35
|
+
*
|
|
36
|
+
* Low-level record manipulation methods.
|
|
37
|
+
*
|
|
38
|
+
* A note about perf: we use long-hand property access rather than computed
|
|
39
|
+
* properties in this file for speed ie.
|
|
40
|
+
*
|
|
41
|
+
* const object = {};
|
|
42
|
+
* object[KEY] = value;
|
|
43
|
+
* record[storageKey] = object;
|
|
44
|
+
*
|
|
45
|
+
* instead of:
|
|
46
|
+
*
|
|
47
|
+
* record[storageKey] = {
|
|
48
|
+
* [KEY]: value,
|
|
49
|
+
* };
|
|
50
|
+
*
|
|
51
|
+
* The latter gets transformed by Babel into something like:
|
|
52
|
+
*
|
|
53
|
+
* function _defineProperty(obj, key, value) {
|
|
54
|
+
* if (key in obj) {
|
|
55
|
+
* Object.defineProperty(obj, key, {
|
|
56
|
+
* value: value,
|
|
57
|
+
* enumerable: true,
|
|
58
|
+
* configurable: true,
|
|
59
|
+
* writable: true,
|
|
60
|
+
* });
|
|
61
|
+
* } else {
|
|
62
|
+
* obj[key] = value;
|
|
63
|
+
* }
|
|
64
|
+
* return obj;
|
|
65
|
+
* }
|
|
66
|
+
*
|
|
67
|
+
* record[storageKey] = _defineProperty({}, KEY, value);
|
|
68
|
+
*
|
|
69
|
+
* A quick benchmark shows that computed property access is an order of
|
|
70
|
+
* magnitude slower (times in seconds for 100,000 iterations):
|
|
71
|
+
*
|
|
72
|
+
* best avg sd
|
|
73
|
+
* computed 0.02175 0.02292 0.00113
|
|
74
|
+
* manual 0.00110 0.00123 0.00008
|
|
75
|
+
*/
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @public
|
|
79
|
+
*
|
|
80
|
+
* Clone a record.
|
|
81
|
+
*/
|
|
82
|
+
function clone(record: Record): Record {
|
|
83
|
+
return {
|
|
84
|
+
...record,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @public
|
|
90
|
+
*
|
|
91
|
+
* Copies all fields from `source` to `sink`, excluding `__id` and `__typename`.
|
|
92
|
+
*
|
|
93
|
+
* NOTE: This function does not treat `id` specially. To preserve the id,
|
|
94
|
+
* manually reset it after calling this function. Also note that values are
|
|
95
|
+
* copied by reference and not value; callers should ensure that values are
|
|
96
|
+
* copied on write.
|
|
97
|
+
*/
|
|
98
|
+
function copyFields(source: Record, sink: Record): void {
|
|
99
|
+
for (const key in source) {
|
|
100
|
+
if (source.hasOwnProperty(key)) {
|
|
101
|
+
if (key !== ID_KEY && key !== TYPENAME_KEY) {
|
|
102
|
+
sink[key] = source[key];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @public
|
|
110
|
+
*
|
|
111
|
+
* Create a new record.
|
|
112
|
+
*/
|
|
113
|
+
function create(dataID: DataID, typeName: string): Record {
|
|
114
|
+
// See perf note above for why we aren't using computed property access.
|
|
115
|
+
const record = {};
|
|
116
|
+
record[ID_KEY] = dataID;
|
|
117
|
+
record[TYPENAME_KEY] = typeName;
|
|
118
|
+
return record;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @public
|
|
123
|
+
*
|
|
124
|
+
* Get the record's `id` if available or the client-generated identifier.
|
|
125
|
+
*/
|
|
126
|
+
function getDataID(record: Record): DataID {
|
|
127
|
+
return (record[ID_KEY]: any);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @public
|
|
132
|
+
*
|
|
133
|
+
* Get the concrete type of the record.
|
|
134
|
+
*/
|
|
135
|
+
function getType(record: Record): string {
|
|
136
|
+
return (record[TYPENAME_KEY]: any);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* @public
|
|
141
|
+
*
|
|
142
|
+
* Get a scalar (non-link) field value.
|
|
143
|
+
*/
|
|
144
|
+
function getValue(record: Record, storageKey: string): mixed {
|
|
145
|
+
const value = record[storageKey];
|
|
146
|
+
if (value && typeof value === 'object') {
|
|
147
|
+
invariant(
|
|
148
|
+
!value.hasOwnProperty(REF_KEY) && !value.hasOwnProperty(REFS_KEY),
|
|
149
|
+
'RelayModernRecord.getValue(): Expected a scalar (non-link) value for `%s.%s` ' +
|
|
150
|
+
'but found %s.',
|
|
151
|
+
record[ID_KEY],
|
|
152
|
+
storageKey,
|
|
153
|
+
value.hasOwnProperty(REF_KEY)
|
|
154
|
+
? 'a linked record'
|
|
155
|
+
: 'plural linked records',
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
return value;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @public
|
|
163
|
+
*
|
|
164
|
+
* Get the value of a field as a reference to another record. Throws if the
|
|
165
|
+
* field has a different type.
|
|
166
|
+
*/
|
|
167
|
+
function getLinkedRecordID(record: Record, storageKey: string): ?DataID {
|
|
168
|
+
const link = record[storageKey];
|
|
169
|
+
if (link == null) {
|
|
170
|
+
return link;
|
|
171
|
+
}
|
|
172
|
+
invariant(
|
|
173
|
+
typeof link === 'object' && link && typeof link[REF_KEY] === 'string',
|
|
174
|
+
'RelayModernRecord.getLinkedRecordID(): Expected `%s.%s` to be a linked ID, ' +
|
|
175
|
+
'was `%s`.',
|
|
176
|
+
record[ID_KEY],
|
|
177
|
+
storageKey,
|
|
178
|
+
JSON.stringify(link),
|
|
179
|
+
);
|
|
180
|
+
return link[REF_KEY];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* @public
|
|
185
|
+
*
|
|
186
|
+
* Get the value of a field as a list of references to other records. Throws if
|
|
187
|
+
* the field has a different type.
|
|
188
|
+
*/
|
|
189
|
+
function getLinkedRecordIDs(
|
|
190
|
+
record: Record,
|
|
191
|
+
storageKey: string,
|
|
192
|
+
): ?Array<?DataID> {
|
|
193
|
+
const links = record[storageKey];
|
|
194
|
+
if (links == null) {
|
|
195
|
+
return links;
|
|
196
|
+
}
|
|
197
|
+
invariant(
|
|
198
|
+
typeof links === 'object' && Array.isArray(links[REFS_KEY]),
|
|
199
|
+
'RelayModernRecord.getLinkedRecordIDs(): Expected `%s.%s` to contain an array ' +
|
|
200
|
+
'of linked IDs, got `%s`.',
|
|
201
|
+
record[ID_KEY],
|
|
202
|
+
storageKey,
|
|
203
|
+
JSON.stringify(links),
|
|
204
|
+
);
|
|
205
|
+
// assume items of the array are ids
|
|
206
|
+
return (links[REFS_KEY]: any);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* @public
|
|
211
|
+
*
|
|
212
|
+
* Returns the epoch at which the record was invalidated, if it
|
|
213
|
+
* ever was; otherwise returns null;
|
|
214
|
+
*/
|
|
215
|
+
function getInvalidationEpoch(record: ?Record): ?number {
|
|
216
|
+
if (record == null) {
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const invalidatedAt = record[INVALIDATED_AT_KEY];
|
|
221
|
+
if (typeof invalidatedAt !== 'number') {
|
|
222
|
+
// If the record has never been invalidated, it isn't stale.
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
return invalidatedAt;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* @public
|
|
230
|
+
*
|
|
231
|
+
* Compares the fields of a previous and new record, returning either the
|
|
232
|
+
* previous record if all fields are equal or a new record (with merged fields)
|
|
233
|
+
* if any fields have changed.
|
|
234
|
+
*/
|
|
235
|
+
function update(prevRecord: Record, nextRecord: Record): Record {
|
|
236
|
+
if (__DEV__) {
|
|
237
|
+
const prevID = getDataID(prevRecord);
|
|
238
|
+
const nextID = getDataID(nextRecord);
|
|
239
|
+
warning(
|
|
240
|
+
prevID === nextID,
|
|
241
|
+
'RelayModernRecord: Invalid record update, expected both versions of ' +
|
|
242
|
+
'the record to have the same id, got `%s` and `%s`.',
|
|
243
|
+
prevID,
|
|
244
|
+
nextID,
|
|
245
|
+
);
|
|
246
|
+
// note: coalesce null/undefined to null
|
|
247
|
+
const prevType = getType(prevRecord) ?? null;
|
|
248
|
+
const nextType = getType(nextRecord) ?? null;
|
|
249
|
+
warning(
|
|
250
|
+
(isClientID(nextID) && nextID !== ROOT_ID) || prevType === nextType,
|
|
251
|
+
'RelayModernRecord: Invalid record update, expected both versions of ' +
|
|
252
|
+
'record `%s` to have the same `%s` but got conflicting types `%s` ' +
|
|
253
|
+
'and `%s`. The GraphQL server likely violated the globally unique ' +
|
|
254
|
+
'id requirement by returning the same id for different objects.',
|
|
255
|
+
prevID,
|
|
256
|
+
TYPENAME_KEY,
|
|
257
|
+
prevType,
|
|
258
|
+
nextType,
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
let updated: Record | null = null;
|
|
262
|
+
const keys = Object.keys(nextRecord);
|
|
263
|
+
for (let ii = 0; ii < keys.length; ii++) {
|
|
264
|
+
const key = keys[ii];
|
|
265
|
+
if (updated || !areEqual(prevRecord[key], nextRecord[key])) {
|
|
266
|
+
updated = updated !== null ? updated : {...prevRecord};
|
|
267
|
+
updated[key] = nextRecord[key];
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return updated !== null ? updated : prevRecord;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* @public
|
|
275
|
+
*
|
|
276
|
+
* Returns a new record with the contents of the given records. Fields in the
|
|
277
|
+
* second record will overwrite identical fields in the first record.
|
|
278
|
+
*/
|
|
279
|
+
function merge(record1: Record, record2: Record): Record {
|
|
280
|
+
if (__DEV__) {
|
|
281
|
+
const prevID = getDataID(record1);
|
|
282
|
+
const nextID = getDataID(record2);
|
|
283
|
+
warning(
|
|
284
|
+
prevID === nextID,
|
|
285
|
+
'RelayModernRecord: Invalid record merge, expected both versions of ' +
|
|
286
|
+
'the record to have the same id, got `%s` and `%s`.',
|
|
287
|
+
prevID,
|
|
288
|
+
nextID,
|
|
289
|
+
);
|
|
290
|
+
// note: coalesce null/undefined to null
|
|
291
|
+
const prevType = getType(record1) ?? null;
|
|
292
|
+
const nextType = getType(record2) ?? null;
|
|
293
|
+
warning(
|
|
294
|
+
(isClientID(nextID) && nextID !== ROOT_ID) || prevType === nextType,
|
|
295
|
+
'RelayModernRecord: Invalid record merge, expected both versions of ' +
|
|
296
|
+
'record `%s` to have the same `%s` but got conflicting types `%s` ' +
|
|
297
|
+
'and `%s`. The GraphQL server likely violated the globally unique ' +
|
|
298
|
+
'id requirement by returning the same id for different objects.',
|
|
299
|
+
prevID,
|
|
300
|
+
TYPENAME_KEY,
|
|
301
|
+
prevType,
|
|
302
|
+
nextType,
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
return Object.assign({}, record1, record2);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* @public
|
|
310
|
+
*
|
|
311
|
+
* Prevent modifications to the record. Attempts to call `set*` functions on a
|
|
312
|
+
* frozen record will fatal at runtime.
|
|
313
|
+
*/
|
|
314
|
+
function freeze(record: Record): void {
|
|
315
|
+
deepFreeze(record);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* @public
|
|
320
|
+
*
|
|
321
|
+
* Set the value of a storageKey to a scalar.
|
|
322
|
+
*/
|
|
323
|
+
function setValue(record: Record, storageKey: string, value: mixed): void {
|
|
324
|
+
if (__DEV__) {
|
|
325
|
+
const prevID = getDataID(record);
|
|
326
|
+
if (storageKey === ID_KEY) {
|
|
327
|
+
warning(
|
|
328
|
+
prevID === value,
|
|
329
|
+
'RelayModernRecord: Invalid field update, expected both versions of ' +
|
|
330
|
+
'the record to have the same id, got `%s` and `%s`.',
|
|
331
|
+
prevID,
|
|
332
|
+
value,
|
|
333
|
+
);
|
|
334
|
+
} else if (storageKey === TYPENAME_KEY) {
|
|
335
|
+
// note: coalesce null/undefined to null
|
|
336
|
+
const prevType = getType(record) ?? null;
|
|
337
|
+
const nextType = value ?? null;
|
|
338
|
+
warning(
|
|
339
|
+
(isClientID(getDataID(record)) && getDataID(record) !== ROOT_ID) ||
|
|
340
|
+
prevType === nextType,
|
|
341
|
+
'RelayModernRecord: Invalid field update, expected both versions of ' +
|
|
342
|
+
'record `%s` to have the same `%s` but got conflicting types `%s` ' +
|
|
343
|
+
'and `%s`. The GraphQL server likely violated the globally unique ' +
|
|
344
|
+
'id requirement by returning the same id for different objects.',
|
|
345
|
+
prevID,
|
|
346
|
+
TYPENAME_KEY,
|
|
347
|
+
prevType,
|
|
348
|
+
nextType,
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
record[storageKey] = value;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* @public
|
|
357
|
+
*
|
|
358
|
+
* Set the value of a field to a reference to another record.
|
|
359
|
+
*/
|
|
360
|
+
function setLinkedRecordID(
|
|
361
|
+
record: Record,
|
|
362
|
+
storageKey: string,
|
|
363
|
+
linkedID: DataID,
|
|
364
|
+
): void {
|
|
365
|
+
// See perf note above for why we aren't using computed property access.
|
|
366
|
+
const link = {};
|
|
367
|
+
link[REF_KEY] = linkedID;
|
|
368
|
+
record[storageKey] = link;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* @public
|
|
373
|
+
*
|
|
374
|
+
* Set the value of a field to a list of references other records.
|
|
375
|
+
*/
|
|
376
|
+
function setLinkedRecordIDs(
|
|
377
|
+
record: Record,
|
|
378
|
+
storageKey: string,
|
|
379
|
+
linkedIDs: Array<?DataID>,
|
|
380
|
+
): void {
|
|
381
|
+
// See perf note above for why we aren't using computed property access.
|
|
382
|
+
const links = {};
|
|
383
|
+
links[REFS_KEY] = linkedIDs;
|
|
384
|
+
record[storageKey] = links;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
module.exports = {
|
|
388
|
+
clone,
|
|
389
|
+
copyFields,
|
|
390
|
+
create,
|
|
391
|
+
freeze,
|
|
392
|
+
getDataID,
|
|
393
|
+
getInvalidationEpoch,
|
|
394
|
+
getLinkedRecordID,
|
|
395
|
+
getLinkedRecordIDs,
|
|
396
|
+
getType,
|
|
397
|
+
getValue,
|
|
398
|
+
merge,
|
|
399
|
+
setValue,
|
|
400
|
+
setLinkedRecordID,
|
|
401
|
+
setLinkedRecordIDs,
|
|
402
|
+
update,
|
|
403
|
+
};
|