@ember-data/store 4.6.1 → 4.7.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/addon/-debug/index.js +35 -13
- package/addon/-private/{identifier-cache.ts → caches/identifier-cache.ts} +148 -73
- package/addon/-private/caches/instance-cache.ts +690 -0
- package/addon/-private/{record-data-for.ts → caches/record-data-for.ts} +2 -7
- package/addon/-private/index.ts +44 -24
- package/addon/-private/{model → legacy-model-support}/record-reference.ts +15 -13
- package/addon/-private/{schema-definition-service.ts → legacy-model-support/schema-definition-service.ts} +13 -9
- package/addon/-private/{model → legacy-model-support}/shim-model-class.ts +18 -11
- package/addon/-private/managers/record-array-manager.ts +377 -0
- package/addon/-private/managers/record-data-manager.ts +845 -0
- package/addon/-private/managers/record-data-store-wrapper.ts +421 -0
- package/addon/-private/managers/record-notification-manager.ts +109 -0
- package/addon/-private/network/fetch-manager.ts +567 -0
- package/addon/-private/{finders.js → network/finders.js} +14 -17
- package/addon/-private/{request-cache.ts → network/request-cache.ts} +21 -18
- package/addon/-private/{snapshot-record-array.ts → network/snapshot-record-array.ts} +14 -31
- package/addon/-private/{snapshot.ts → network/snapshot.ts} +40 -49
- package/addon/-private/{promise-proxies.ts → proxies/promise-proxies.ts} +76 -15
- package/addon/-private/{promise-proxy-base.js → proxies/promise-proxy-base.js} +0 -0
- package/addon/-private/record-arrays/identifier-array.ts +924 -0
- package/addon/-private/{core-store.ts → store-service.ts} +574 -215
- package/addon/-private/{coerce-id.ts → utils/coerce-id.ts} +1 -1
- package/addon/-private/{common.js → utils/common.js} +1 -2
- package/addon/-private/utils/construct-resource.ts +2 -2
- package/addon/-private/{identifer-debug-consts.ts → utils/identifer-debug-consts.ts} +0 -0
- package/addon/-private/utils/is-non-empty-string.ts +1 -1
- package/addon/-private/{normalize-model-name.ts → utils/normalize-model-name.ts} +1 -3
- package/addon/-private/utils/promise-record.ts +5 -6
- package/addon/-private/{serializer-response.ts → utils/serializer-response.ts} +2 -2
- package/addon/-private/utils/uuid-polyfill.ts +73 -0
- package/package.json +12 -8
- package/addon/-private/backburner.js +0 -25
- package/addon/-private/errors-utils.js +0 -146
- package/addon/-private/fetch-manager.ts +0 -597
- package/addon/-private/identity-map.ts +0 -54
- package/addon/-private/instance-cache.ts +0 -387
- package/addon/-private/internal-model-factory.ts +0 -359
- package/addon/-private/internal-model-map.ts +0 -121
- package/addon/-private/model/internal-model.ts +0 -602
- package/addon/-private/record-array-manager.ts +0 -444
- package/addon/-private/record-arrays/adapter-populated-record-array.ts +0 -130
- package/addon/-private/record-arrays/record-array.ts +0 -318
- package/addon/-private/record-data-store-wrapper.ts +0 -243
- package/addon/-private/record-notification-manager.ts +0 -73
- package/addon/-private/weak-cache.ts +0 -125
|
@@ -1,387 +0,0 @@
|
|
|
1
|
-
import { assert } from '@ember/debug';
|
|
2
|
-
import { DEBUG } from '@glimmer/env';
|
|
3
|
-
|
|
4
|
-
import { resolve } from 'rsvp';
|
|
5
|
-
|
|
6
|
-
import type { ExistingResourceObject, ResourceIdentifierObject } from '@ember-data/types/q/ember-data-json-api';
|
|
7
|
-
import type {
|
|
8
|
-
RecordIdentifier,
|
|
9
|
-
StableExistingRecordIdentifier,
|
|
10
|
-
StableRecordIdentifier,
|
|
11
|
-
} from '@ember-data/types/q/identifier';
|
|
12
|
-
import type { RecordData } from '@ember-data/types/q/record-data';
|
|
13
|
-
import type { RecordInstance } from '@ember-data/types/q/record-instance';
|
|
14
|
-
import type { FindOptions } from '@ember-data/types/q/store';
|
|
15
|
-
|
|
16
|
-
import coerceId, { ensureStringId } from './coerce-id';
|
|
17
|
-
import type { CreateRecordProperties } from './core-store';
|
|
18
|
-
import type Store from './core-store';
|
|
19
|
-
import { assertIdentifierHasId } from './core-store';
|
|
20
|
-
import { internalModelFactoryFor, setRecordIdentifier } from './internal-model-factory';
|
|
21
|
-
import InternalModel from './model/internal-model';
|
|
22
|
-
import RecordReference from './model/record-reference';
|
|
23
|
-
import normalizeModelName from './normalize-model-name';
|
|
24
|
-
import recordDataFor, { setRecordDataFor } from './record-data-for';
|
|
25
|
-
import RecordDataStoreWrapper from './record-data-store-wrapper';
|
|
26
|
-
import Snapshot from './snapshot';
|
|
27
|
-
import constructResource from './utils/construct-resource';
|
|
28
|
-
import WeakCache from './weak-cache';
|
|
29
|
-
|
|
30
|
-
const RECORD_REFERENCES = new WeakCache<StableRecordIdentifier, RecordReference>(DEBUG ? 'reference' : '');
|
|
31
|
-
export const StoreMap = new WeakCache<RecordInstance, Store>(DEBUG ? 'store' : '');
|
|
32
|
-
|
|
33
|
-
export function storeFor(record: RecordInstance): Store | undefined {
|
|
34
|
-
const store = StoreMap.get(record);
|
|
35
|
-
|
|
36
|
-
assert(
|
|
37
|
-
`A record in a disconnected state cannot utilize the store. This typically means the record has been destroyed, most commonly by unloading it.`,
|
|
38
|
-
store
|
|
39
|
-
);
|
|
40
|
-
return store;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
type Caches = {
|
|
44
|
-
record: WeakMap<StableRecordIdentifier, RecordInstance>;
|
|
45
|
-
recordData: WeakMap<StableRecordIdentifier, RecordData>;
|
|
46
|
-
};
|
|
47
|
-
export class InstanceCache {
|
|
48
|
-
declare store: Store;
|
|
49
|
-
declare _storeWrapper: RecordDataStoreWrapper;
|
|
50
|
-
|
|
51
|
-
#instances: Caches = {
|
|
52
|
-
record: new WeakMap<StableRecordIdentifier, RecordInstance>(),
|
|
53
|
-
recordData: new WeakMap<StableRecordIdentifier, RecordData>(),
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
constructor(store: Store) {
|
|
57
|
-
this.store = store;
|
|
58
|
-
|
|
59
|
-
this._storeWrapper = new RecordDataStoreWrapper(this.store);
|
|
60
|
-
this.__recordDataFor = this.__recordDataFor.bind(this);
|
|
61
|
-
|
|
62
|
-
RECORD_REFERENCES._generator = (identifier) => {
|
|
63
|
-
return new RecordReference(this.store, identifier);
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
peek({ identifier, bucket }: { identifier: StableRecordIdentifier; bucket: 'record' }): RecordInstance | undefined;
|
|
67
|
-
peek({ identifier, bucket }: { identifier: StableRecordIdentifier; bucket: 'recordData' }): RecordData | undefined;
|
|
68
|
-
peek({
|
|
69
|
-
identifier,
|
|
70
|
-
bucket,
|
|
71
|
-
}: {
|
|
72
|
-
identifier: StableRecordIdentifier;
|
|
73
|
-
bucket: 'record' | 'recordData';
|
|
74
|
-
}): RecordData | RecordInstance | undefined {
|
|
75
|
-
return this.#instances[bucket]?.get(identifier);
|
|
76
|
-
}
|
|
77
|
-
set({
|
|
78
|
-
identifier,
|
|
79
|
-
bucket,
|
|
80
|
-
value,
|
|
81
|
-
}: {
|
|
82
|
-
identifier: StableRecordIdentifier;
|
|
83
|
-
bucket: 'record';
|
|
84
|
-
value: RecordInstance;
|
|
85
|
-
}): void {
|
|
86
|
-
this.#instances[bucket].set(identifier, value);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
getRecord(identifier: StableRecordIdentifier, properties?: CreateRecordProperties): RecordInstance {
|
|
90
|
-
let record = this.peek({ identifier, bucket: 'record' });
|
|
91
|
-
|
|
92
|
-
if (!record) {
|
|
93
|
-
// TODO store this state somewhere better
|
|
94
|
-
const internalModel = this.getInternalModel(identifier);
|
|
95
|
-
|
|
96
|
-
if (internalModel._isDematerializing) {
|
|
97
|
-
// TODO this should be an assertion, this likely means
|
|
98
|
-
// we have a bug to find wherein our own store is calling this
|
|
99
|
-
// with an identifier that should have already been disconnected.
|
|
100
|
-
// the destroy + fetch again case is likely either preserving the
|
|
101
|
-
// identifier for re-use or failing to unload it.
|
|
102
|
-
return null as unknown as RecordInstance;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// TODO store this state somewhere better
|
|
106
|
-
internalModel.hasRecord = true;
|
|
107
|
-
|
|
108
|
-
if (properties && 'id' in properties) {
|
|
109
|
-
assert(`expected id to be a string or null`, properties.id !== undefined);
|
|
110
|
-
internalModel.setId(properties.id);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
record = this._instantiateRecord(this.getRecordData(identifier), identifier, properties);
|
|
114
|
-
this.set({ identifier, bucket: 'record', value: record });
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return record;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
getReference(identifier: StableRecordIdentifier) {
|
|
121
|
-
return RECORD_REFERENCES.lookup(identifier);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
_fetchDataIfNeededForIdentifier(
|
|
125
|
-
identifier: StableRecordIdentifier,
|
|
126
|
-
options: FindOptions = {}
|
|
127
|
-
): Promise<StableRecordIdentifier> {
|
|
128
|
-
const internalModel = this.getInternalModel(identifier);
|
|
129
|
-
|
|
130
|
-
// pre-loading will change the isEmpty value
|
|
131
|
-
// TODO stpre this state somewhere other than InternalModel
|
|
132
|
-
const { isEmpty, isLoading } = internalModel;
|
|
133
|
-
|
|
134
|
-
if (options.preload) {
|
|
135
|
-
this.store._backburner.join(() => {
|
|
136
|
-
internalModel.preloadData(options.preload);
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
let promise: Promise<StableRecordIdentifier>;
|
|
141
|
-
if (isEmpty) {
|
|
142
|
-
assertIdentifierHasId(identifier);
|
|
143
|
-
|
|
144
|
-
promise = this.store._fetchManager.scheduleFetch(identifier, options);
|
|
145
|
-
} else if (isLoading) {
|
|
146
|
-
promise = this.store._fetchManager.getPendingFetch(identifier, options)!;
|
|
147
|
-
assert(`Expected to find a pending request for a record in the loading state, but found none`, promise);
|
|
148
|
-
} else {
|
|
149
|
-
promise = resolve(identifier);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return promise;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
_instantiateRecord(
|
|
156
|
-
recordData: RecordData,
|
|
157
|
-
identifier: StableRecordIdentifier,
|
|
158
|
-
properties?: { [key: string]: unknown }
|
|
159
|
-
) {
|
|
160
|
-
// assert here
|
|
161
|
-
if (properties !== undefined) {
|
|
162
|
-
assert(
|
|
163
|
-
`You passed '${typeof properties}' as properties for record creation instead of an object.`,
|
|
164
|
-
typeof properties === 'object' && properties !== null
|
|
165
|
-
);
|
|
166
|
-
|
|
167
|
-
const { type } = identifier;
|
|
168
|
-
|
|
169
|
-
// convert relationship Records to RecordDatas before passing to RecordData
|
|
170
|
-
let defs = this.store.getSchemaDefinitionService().relationshipsDefinitionFor({ type });
|
|
171
|
-
|
|
172
|
-
if (defs !== null) {
|
|
173
|
-
let keys = Object.keys(properties);
|
|
174
|
-
let relationshipValue;
|
|
175
|
-
|
|
176
|
-
for (let i = 0; i < keys.length; i++) {
|
|
177
|
-
let prop = keys[i];
|
|
178
|
-
let def = defs[prop];
|
|
179
|
-
|
|
180
|
-
if (def !== undefined) {
|
|
181
|
-
if (def.kind === 'hasMany') {
|
|
182
|
-
if (DEBUG) {
|
|
183
|
-
assertRecordsPassedToHasMany(properties[prop] as RecordInstance[]);
|
|
184
|
-
}
|
|
185
|
-
relationshipValue = extractRecordDatasFromRecords(properties[prop] as RecordInstance[]);
|
|
186
|
-
} else {
|
|
187
|
-
relationshipValue = extractRecordDataFromRecord(properties[prop] as RecordInstance);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
properties[prop] = relationshipValue;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// TODO guard against initRecordOptions no being there
|
|
197
|
-
let createOptions = recordData._initRecordCreateOptions(properties);
|
|
198
|
-
//TODO Igor pass a wrapper instead of RD
|
|
199
|
-
let record = this.store.instantiateRecord(
|
|
200
|
-
identifier,
|
|
201
|
-
createOptions,
|
|
202
|
-
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
203
|
-
this.__recordDataFor,
|
|
204
|
-
this.store._notificationManager
|
|
205
|
-
);
|
|
206
|
-
setRecordIdentifier(record, identifier);
|
|
207
|
-
setRecordDataFor(record, recordData);
|
|
208
|
-
StoreMap.set(record, this.store);
|
|
209
|
-
return record;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
_teardownRecord(record: RecordInstance) {
|
|
213
|
-
StoreMap.delete(record);
|
|
214
|
-
// TODO remove identifier:record cache link
|
|
215
|
-
this.store.teardownRecord(record);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
removeRecord(identifier: StableRecordIdentifier): boolean {
|
|
219
|
-
let record = this.peek({ identifier, bucket: 'record' });
|
|
220
|
-
|
|
221
|
-
if (record) {
|
|
222
|
-
this.#instances.record.delete(identifier);
|
|
223
|
-
this._teardownRecord(record);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
return !!record;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
// TODO move RecordData Cache into InstanceCache
|
|
230
|
-
getRecordData(identifier: StableRecordIdentifier) {
|
|
231
|
-
let recordData = this.peek({ identifier, bucket: 'recordData' });
|
|
232
|
-
|
|
233
|
-
if (!recordData) {
|
|
234
|
-
recordData = this._createRecordData(identifier);
|
|
235
|
-
this.#instances.recordData.set(identifier, recordData);
|
|
236
|
-
this.getInternalModel(identifier).hasRecordData = true;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
return recordData;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// TODO move InternalModel cache into InstanceCache
|
|
243
|
-
getInternalModel(identifier: StableRecordIdentifier) {
|
|
244
|
-
return this._internalModelForResource(identifier);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
createSnapshot(identifier: StableRecordIdentifier, options: FindOptions = {}): Snapshot {
|
|
248
|
-
return new Snapshot(options, identifier, this.store);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
__recordDataFor(resource: RecordIdentifier) {
|
|
252
|
-
const identifier = this.store.identifierCache.getOrCreateRecordIdentifier(resource);
|
|
253
|
-
return this.recordDataFor(identifier, false);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// TODO move this to InstanceCache
|
|
257
|
-
_createRecordData(identifier: StableRecordIdentifier): RecordData {
|
|
258
|
-
const recordData = this.store.createRecordDataFor(
|
|
259
|
-
identifier.type,
|
|
260
|
-
identifier.id,
|
|
261
|
-
identifier.lid,
|
|
262
|
-
this._storeWrapper
|
|
263
|
-
);
|
|
264
|
-
setRecordDataFor(identifier, recordData);
|
|
265
|
-
// TODO this is invalid for v2 recordData but required
|
|
266
|
-
// for v1 recordData. Remember to remove this once the
|
|
267
|
-
// RecordData manager handles converting recordData to identifier
|
|
268
|
-
setRecordIdentifier(recordData, identifier);
|
|
269
|
-
return recordData;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// TODO string candidate for early elimination
|
|
273
|
-
_internalModelForResource(resource: ResourceIdentifierObject): InternalModel {
|
|
274
|
-
return internalModelFactoryFor(this.store).getByResource(resource);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
setRecordId(modelName: string, newId: string, clientId: string) {
|
|
278
|
-
internalModelFactoryFor(this.store).setRecordId(modelName, newId, clientId);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
_load(data: ExistingResourceObject): StableExistingRecordIdentifier {
|
|
282
|
-
// TODO type should be pulled from the identifier for debug
|
|
283
|
-
let modelName = data.type;
|
|
284
|
-
assert(
|
|
285
|
-
`You must include an 'id' for ${modelName} in an object passed to 'push'`,
|
|
286
|
-
data.id !== null && data.id !== undefined && data.id !== ''
|
|
287
|
-
);
|
|
288
|
-
assert(
|
|
289
|
-
`You tried to push data with a type '${modelName}' but no model could be found with that name.`,
|
|
290
|
-
this.store.getSchemaDefinitionService().doesTypeExist(modelName)
|
|
291
|
-
);
|
|
292
|
-
|
|
293
|
-
// TODO this should determine identifier via the cache before making assumptions
|
|
294
|
-
const resource = constructResource(normalizeModelName(data.type), ensureStringId(data.id), coerceId(data.lid));
|
|
295
|
-
const maybeIdentifier = this.store.identifierCache.peekRecordIdentifier(resource);
|
|
296
|
-
|
|
297
|
-
let internalModel = internalModelFactoryFor(this.store).lookup(resource, data);
|
|
298
|
-
|
|
299
|
-
// store.push will be from empty
|
|
300
|
-
// findRecord will be from root.loading
|
|
301
|
-
// this cannot be loading state if we do not already have an identifier
|
|
302
|
-
// all else will be updates
|
|
303
|
-
const isLoading = internalModel.isLoading || (!internalModel.isLoaded && maybeIdentifier);
|
|
304
|
-
const isUpdate = internalModel.isEmpty === false && !isLoading;
|
|
305
|
-
|
|
306
|
-
// exclude store.push (root.empty) case
|
|
307
|
-
let identifier = internalModel.identifier;
|
|
308
|
-
if (isUpdate || isLoading) {
|
|
309
|
-
let updatedIdentifier = this.store.identifierCache.updateRecordIdentifier(identifier, data);
|
|
310
|
-
|
|
311
|
-
if (updatedIdentifier !== identifier) {
|
|
312
|
-
// we encountered a merge of identifiers in which
|
|
313
|
-
// two identifiers (and likely two internalModels)
|
|
314
|
-
// existed for the same resource. Now that we have
|
|
315
|
-
// determined the correct identifier to use, make sure
|
|
316
|
-
// that we also use the correct internalModel.
|
|
317
|
-
identifier = updatedIdentifier;
|
|
318
|
-
internalModel = internalModelFactoryFor(this.store).lookup(identifier);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
internalModel.setupData(data);
|
|
323
|
-
|
|
324
|
-
if (!isUpdate) {
|
|
325
|
-
this.store.recordArrayManager.recordDidChange(identifier);
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
return identifier as StableExistingRecordIdentifier;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
recordDataFor(identifier: StableRecordIdentifier | { type: string }, isCreate: boolean): RecordData {
|
|
332
|
-
let recordData: RecordData;
|
|
333
|
-
if (isCreate === true) {
|
|
334
|
-
// TODO remove once InternalModel is no longer essential to internal state
|
|
335
|
-
// and just build a new identifier directly
|
|
336
|
-
let internalModel = internalModelFactoryFor(this.store).build({ type: identifier.type, id: null });
|
|
337
|
-
let stableIdentifier = internalModel.identifier;
|
|
338
|
-
recordData = this.getRecordData(stableIdentifier);
|
|
339
|
-
recordData.clientDidCreate();
|
|
340
|
-
this.store.recordArrayManager.recordDidChange(stableIdentifier);
|
|
341
|
-
} else {
|
|
342
|
-
// TODO remove once InternalModel is no longer essential to internal state
|
|
343
|
-
internalModelFactoryFor(this.store).lookup(identifier as StableRecordIdentifier);
|
|
344
|
-
recordData = this.getRecordData(identifier as StableRecordIdentifier);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
return recordData;
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
function assertRecordsPassedToHasMany(records: RecordInstance[]) {
|
|
352
|
-
assert(`You must pass an array of records to set a hasMany relationship`, Array.isArray(records));
|
|
353
|
-
assert(
|
|
354
|
-
`All elements of a hasMany relationship must be instances of Model, you passed ${records
|
|
355
|
-
.map((r) => `${typeof r}`)
|
|
356
|
-
.join(', ')}`,
|
|
357
|
-
(function () {
|
|
358
|
-
return records.every((record) => Object.prototype.hasOwnProperty.call(record, '_internalModel') === true);
|
|
359
|
-
})()
|
|
360
|
-
);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
function extractRecordDatasFromRecords(records: RecordInstance[]): RecordData[] {
|
|
364
|
-
return records.map(extractRecordDataFromRecord) as RecordData[];
|
|
365
|
-
}
|
|
366
|
-
type PromiseProxyRecord = { then(): void; get(str: 'content'): RecordInstance | null | undefined };
|
|
367
|
-
|
|
368
|
-
function extractRecordDataFromRecord(recordOrPromiseRecord: PromiseProxyRecord | RecordInstance | null) {
|
|
369
|
-
if (!recordOrPromiseRecord) {
|
|
370
|
-
return null;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
if (isPromiseRecord(recordOrPromiseRecord)) {
|
|
374
|
-
let content = recordOrPromiseRecord.get && recordOrPromiseRecord.get('content');
|
|
375
|
-
assert(
|
|
376
|
-
'You passed in a promise that did not originate from an EmberData relationship. You can only pass promises that come from a belongsTo or hasMany relationship to the get call.',
|
|
377
|
-
content !== undefined
|
|
378
|
-
);
|
|
379
|
-
return content ? recordDataFor(content) : null;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
return recordDataFor(recordOrPromiseRecord);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
function isPromiseRecord(record: PromiseProxyRecord | RecordInstance): record is PromiseProxyRecord {
|
|
386
|
-
return !!record.then;
|
|
387
|
-
}
|