@ember-data/store 4.4.0-alpha.9 → 4.4.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/addon/-private/system/core-store.ts +147 -134
- package/addon/-private/system/ds-model-store.ts +10 -1
- package/addon/-private/system/fetch-manager.ts +21 -48
- package/addon/-private/system/model/internal-model.ts +192 -263
- package/addon/-private/system/model/states.js +41 -5
- package/addon/-private/system/{promise-proxies.ts → promise-proxies.js} +21 -31
- package/addon/-private/system/{record-array-manager.ts → record-array-manager.js} +60 -87
- package/addon/-private/system/record-arrays/adapter-populated-record-array.js +95 -0
- package/addon/-private/system/record-arrays/{record-array.ts → record-array.js} +75 -96
- package/addon/-private/system/record-data-for.ts +0 -2
- package/addon/-private/system/references/belongs-to.ts +2 -3
- package/addon/-private/system/references/has-many.ts +2 -4
- package/addon/-private/system/schema-definition-service.ts +2 -2
- package/addon/-private/system/snapshot-record-array.ts +11 -12
- package/addon/-private/system/snapshot.ts +7 -24
- package/addon/-private/system/store/common.js +1 -24
- package/addon/-private/system/store/finders.js +5 -53
- package/addon/-private/system/store/internal-model-factory.ts +7 -8
- package/addon/-private/system/store/record-data-store-wrapper.ts +2 -7
- package/addon/-private/system/store/serializer-response.js +71 -0
- package/addon/-private/ts-interfaces/ds-model.ts +7 -15
- package/addon/-private/ts-interfaces/ember-data-json-api.ts +0 -3
- package/addon/-private/ts-interfaces/minimum-adapter-interface.ts +20 -19
- package/addon/-private/ts-interfaces/minimum-serializer-interface.ts +6 -27
- package/addon/-private/ts-interfaces/record-data.ts +1 -4
- package/addon/-private/ts-interfaces/record-instance.ts +1 -3
- package/addon/-private/ts-interfaces/store.ts +0 -1
- package/addon/-private/utils/promise-record.ts +3 -3
- package/index.js +0 -3
- package/package.json +6 -7
- package/addon/-private/system/promise-proxy-base.js +0 -7
- package/addon/-private/system/record-arrays/adapter-populated-record-array.ts +0 -129
- package/addon/-private/system/store/serializer-response.ts +0 -85
|
@@ -13,14 +13,19 @@ import { isNone, isPresent, typeOf } from '@ember/utils';
|
|
|
13
13
|
import { DEBUG } from '@glimmer/env';
|
|
14
14
|
import Ember from 'ember';
|
|
15
15
|
|
|
16
|
-
import
|
|
17
|
-
import { all, default as RSVP, resolve } from 'rsvp';
|
|
16
|
+
import require from 'require';
|
|
17
|
+
import { all, default as RSVP, Promise, resolve } from 'rsvp';
|
|
18
18
|
|
|
19
19
|
import { HAS_RECORD_DATA_PACKAGE } from '@ember-data/private-build-infra';
|
|
20
|
-
import type {
|
|
20
|
+
import type {
|
|
21
|
+
BelongsToRelationship,
|
|
22
|
+
ManyRelationship,
|
|
23
|
+
RecordData as RecordDataClass,
|
|
24
|
+
} from '@ember-data/record-data/-private';
|
|
21
25
|
import type { RelationshipState } from '@ember-data/record-data/-private/graph/-state';
|
|
22
26
|
|
|
23
27
|
import { IdentifierCache } from '../identifiers/cache';
|
|
28
|
+
import type { DSModel } from '../ts-interfaces/ds-model';
|
|
24
29
|
import type {
|
|
25
30
|
CollectionResourceDocument,
|
|
26
31
|
EmptyResourceDocument,
|
|
@@ -34,12 +39,11 @@ import type {
|
|
|
34
39
|
StableExistingRecordIdentifier,
|
|
35
40
|
StableRecordIdentifier,
|
|
36
41
|
} from '../ts-interfaces/identifier';
|
|
37
|
-
import {
|
|
38
|
-
import type { MinimumSerializerInterface } from '../ts-interfaces/minimum-serializer-interface';
|
|
42
|
+
import type { PromiseProxy } from '../ts-interfaces/promise-proxies';
|
|
39
43
|
import type { RecordData } from '../ts-interfaces/record-data';
|
|
40
44
|
import type { JsonApiRelationship } from '../ts-interfaces/record-data-json-api';
|
|
41
45
|
import type { RecordDataRecordWrapper } from '../ts-interfaces/record-data-record-wrapper';
|
|
42
|
-
import type { AttributesSchema
|
|
46
|
+
import type { AttributesSchema } from '../ts-interfaces/record-data-schemas';
|
|
43
47
|
import type { RecordInstance } from '../ts-interfaces/record-instance';
|
|
44
48
|
import type { SchemaDefinitionService } from '../ts-interfaces/schema-definition-service';
|
|
45
49
|
import type { FindOptions } from '../ts-interfaces/store';
|
|
@@ -58,10 +62,8 @@ import {
|
|
|
58
62
|
import type ShimModelClass from './model/shim-model-class';
|
|
59
63
|
import { getShimClass } from './model/shim-model-class';
|
|
60
64
|
import normalizeModelName from './normalize-model-name';
|
|
61
|
-
import type { PromiseArray, PromiseObject } from './promise-proxies';
|
|
62
65
|
import { promiseArray, promiseObject } from './promise-proxies';
|
|
63
66
|
import RecordArrayManager from './record-array-manager';
|
|
64
|
-
import { AdapterPopulatedRecordArray, RecordArray } from './record-arrays';
|
|
65
67
|
import { setRecordDataFor } from './record-data-for';
|
|
66
68
|
import NotificationManager from './record-notification-manager';
|
|
67
69
|
import type { BelongsToReference, HasManyReference } from './references';
|
|
@@ -82,6 +84,7 @@ let _RecordData: RecordDataConstruct | undefined;
|
|
|
82
84
|
|
|
83
85
|
const { ENV } = Ember;
|
|
84
86
|
type AsyncTrackingToken = Readonly<{ label: string; trace: Error | string }>;
|
|
87
|
+
type PromiseArray<T> = Promise<T[]>;
|
|
85
88
|
|
|
86
89
|
const RECORD_REFERENCES = new WeakCache<StableRecordIdentifier, RecordReference>(DEBUG ? 'reference' : '');
|
|
87
90
|
|
|
@@ -93,11 +96,6 @@ function freeze<T>(obj: T): T {
|
|
|
93
96
|
return obj;
|
|
94
97
|
}
|
|
95
98
|
|
|
96
|
-
export interface CreateRecordProperties {
|
|
97
|
-
id?: string | null;
|
|
98
|
-
[key: string]: unknown;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
99
|
/**
|
|
102
100
|
The store contains all of the data for records loaded from the server.
|
|
103
101
|
It is also responsible for creating instances of `Model` that wrap
|
|
@@ -174,31 +172,36 @@ export interface CreateRecordProperties {
|
|
|
174
172
|
|
|
175
173
|
abstract class CoreStore extends Service {
|
|
176
174
|
/**
|
|
177
|
-
* Ember Data uses several specialized micro-queues for organizing
|
|
178
|
-
and coalescing similar async work.
|
|
179
|
-
|
|
180
|
-
These queues are currently controlled by a flush scheduled into
|
|
181
|
-
ember-data's custom backburner instance.
|
|
182
|
-
*
|
|
183
175
|
* EmberData specific backburner instance
|
|
184
176
|
* @property _backburner
|
|
185
177
|
* @private
|
|
186
178
|
*/
|
|
187
|
-
|
|
188
|
-
|
|
179
|
+
public _backburner: Backburner = edBackburner;
|
|
180
|
+
public recordArrayManager: RecordArrayManager = new RecordArrayManager({ store: this });
|
|
189
181
|
|
|
190
182
|
declare _notificationManager: NotificationManager;
|
|
191
183
|
declare identifierCache: IdentifierCache;
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
184
|
+
private _adapterCache = Object.create(null);
|
|
185
|
+
private _serializerCache = Object.create(null);
|
|
186
|
+
public _storeWrapper = new RecordDataStoreWrapper(this);
|
|
187
|
+
|
|
188
|
+
/*
|
|
189
|
+
Ember Data uses several specialized micro-queues for organizing
|
|
190
|
+
and coalescing similar async work.
|
|
191
|
+
|
|
192
|
+
These queues are currently controlled by a flush scheduled into
|
|
193
|
+
ember-data's custom backburner instance.
|
|
194
|
+
*/
|
|
195
|
+
// used for coalescing internal model updates
|
|
196
|
+
private _updatedInternalModels: InternalModel[] = [];
|
|
197
|
+
|
|
195
198
|
declare _fetchManager: FetchManager;
|
|
196
199
|
declare _schemaDefinitionService: SchemaDefinitionService;
|
|
197
200
|
|
|
198
201
|
// DEBUG-only properties
|
|
199
202
|
declare _trackedAsyncRequests: AsyncTrackingToken[];
|
|
200
|
-
|
|
201
|
-
|
|
203
|
+
shouldTrackAsyncRequests: boolean = false;
|
|
204
|
+
generateStackTracesForTrackedRequests: boolean = false;
|
|
202
205
|
declare _trackAsyncRequestStart: (str: string) => void;
|
|
203
206
|
declare _trackAsyncRequestEnd: (token: AsyncTrackingToken) => void;
|
|
204
207
|
declare __asyncWaiter: () => boolean;
|
|
@@ -249,11 +252,6 @@ abstract class CoreStore extends Service {
|
|
|
249
252
|
*/
|
|
250
253
|
constructor() {
|
|
251
254
|
super(...arguments);
|
|
252
|
-
this._adapterCache = Object.create(null);
|
|
253
|
-
this._serializerCache = Object.create(null);
|
|
254
|
-
this._storeWrapper = new RecordDataStoreWrapper(this);
|
|
255
|
-
this._backburner = edBackburner;
|
|
256
|
-
this.recordArrayManager = new RecordArrayManager({ store: this });
|
|
257
255
|
|
|
258
256
|
RECORD_REFERENCES._generator = (identifier) => {
|
|
259
257
|
return new RecordReference(this, identifier);
|
|
@@ -392,14 +390,19 @@ abstract class CoreStore extends Service {
|
|
|
392
390
|
recordDataFor: (identifier: RecordIdentifier) => RecordDataRecordWrapper,
|
|
393
391
|
notificationManager: NotificationManager
|
|
394
392
|
): RecordInstance;
|
|
393
|
+
|
|
395
394
|
abstract teardownRecord(record: RecordInstance): void;
|
|
396
|
-
abstract getSchemaDefinitionService(): SchemaDefinitionService;
|
|
397
395
|
|
|
396
|
+
_internalDeleteRecord(internalModel: InternalModel) {
|
|
397
|
+
internalModel.deleteRecord();
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// FeatureFlagged in the DSModelStore claas
|
|
398
401
|
_attributesDefinitionFor(identifier: RecordIdentifier | { type: string }): AttributesSchema {
|
|
399
402
|
return this.getSchemaDefinitionService().attributesDefinitionFor(identifier);
|
|
400
403
|
}
|
|
401
404
|
|
|
402
|
-
_relationshipsDefinitionFor(identifier: RecordIdentifier | { type: string })
|
|
405
|
+
_relationshipsDefinitionFor(identifier: RecordIdentifier | { type: string }) {
|
|
403
406
|
return this.getSchemaDefinitionService().relationshipsDefinitionFor(identifier);
|
|
404
407
|
}
|
|
405
408
|
|
|
@@ -407,6 +410,11 @@ abstract class CoreStore extends Service {
|
|
|
407
410
|
this._schemaDefinitionService = schema;
|
|
408
411
|
}
|
|
409
412
|
|
|
413
|
+
getSchemaDefinitionService(): SchemaDefinitionService {
|
|
414
|
+
return this._schemaDefinitionService;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// TODO Double check this return value is correct
|
|
410
418
|
_relationshipMetaFor(modelName: string, id: string | null, key: string) {
|
|
411
419
|
return this._relationshipsDefinitionFor({ type: modelName })[key];
|
|
412
420
|
}
|
|
@@ -491,7 +499,7 @@ abstract class CoreStore extends Service {
|
|
|
491
499
|
newly created record.
|
|
492
500
|
@return {Model} record
|
|
493
501
|
*/
|
|
494
|
-
createRecord(modelName
|
|
502
|
+
createRecord(modelName, inputProperties) {
|
|
495
503
|
if (DEBUG) {
|
|
496
504
|
assertDestroyingStore(this, 'createRecord');
|
|
497
505
|
}
|
|
@@ -545,7 +553,7 @@ abstract class CoreStore extends Service {
|
|
|
545
553
|
@param {Object} properties from the new record
|
|
546
554
|
@return {String} if the adapter can generate one, an ID
|
|
547
555
|
*/
|
|
548
|
-
_generateId(modelName
|
|
556
|
+
_generateId(modelName, properties) {
|
|
549
557
|
let adapter = this.adapterFor(modelName);
|
|
550
558
|
|
|
551
559
|
if (adapter && adapter.generateIdForRecord) {
|
|
@@ -576,7 +584,7 @@ abstract class CoreStore extends Service {
|
|
|
576
584
|
@public
|
|
577
585
|
@param {Model} record
|
|
578
586
|
*/
|
|
579
|
-
deleteRecord(record
|
|
587
|
+
deleteRecord(record) {
|
|
580
588
|
if (DEBUG) {
|
|
581
589
|
assertDestroyingStore(this, 'deleteRecord');
|
|
582
590
|
}
|
|
@@ -607,7 +615,7 @@ abstract class CoreStore extends Service {
|
|
|
607
615
|
@public
|
|
608
616
|
@param {Model} record
|
|
609
617
|
*/
|
|
610
|
-
unloadRecord(record
|
|
618
|
+
unloadRecord(record) {
|
|
611
619
|
if (DEBUG) {
|
|
612
620
|
assertDestroyingStore(this, 'unloadRecord');
|
|
613
621
|
}
|
|
@@ -632,7 +640,7 @@ abstract class CoreStore extends Service {
|
|
|
632
640
|
@return {Promise} promise
|
|
633
641
|
@private
|
|
634
642
|
*/
|
|
635
|
-
find(modelName
|
|
643
|
+
find(modelName, id, options) {
|
|
636
644
|
if (DEBUG) {
|
|
637
645
|
assertDestroyingStore(this, 'find');
|
|
638
646
|
}
|
|
@@ -1031,13 +1039,13 @@ abstract class CoreStore extends Service {
|
|
|
1031
1039
|
@param {Object} [options] - if the first param is a string this will be the optional options for the request. See examples for available options.
|
|
1032
1040
|
@return {Promise} promise
|
|
1033
1041
|
*/
|
|
1034
|
-
findRecord(resource: string, id: string | number, options?: FindOptions):
|
|
1035
|
-
findRecord(resource: ResourceIdentifierObject, id?: FindOptions):
|
|
1042
|
+
findRecord(resource: string, id: string | number, options?: FindOptions): PromiseProxy<DSModel>;
|
|
1043
|
+
findRecord(resource: ResourceIdentifierObject, id?: FindOptions): PromiseProxy<DSModel>;
|
|
1036
1044
|
findRecord(
|
|
1037
1045
|
resource: string | ResourceIdentifierObject,
|
|
1038
1046
|
id?: string | number | FindOptions,
|
|
1039
1047
|
options?: FindOptions
|
|
1040
|
-
):
|
|
1048
|
+
): PromiseProxy<DSModel> {
|
|
1041
1049
|
if (DEBUG) {
|
|
1042
1050
|
assertDestroyingStore(this, 'findRecord');
|
|
1043
1051
|
}
|
|
@@ -1062,10 +1070,7 @@ abstract class CoreStore extends Service {
|
|
|
1062
1070
|
options = options || {};
|
|
1063
1071
|
|
|
1064
1072
|
if (!internalModel.currentState.isLoaded) {
|
|
1065
|
-
return
|
|
1066
|
-
this._findByInternalModel(internalModel, options),
|
|
1067
|
-
`DS: Store#findRecord ${internalModel.identifier}`
|
|
1068
|
-
);
|
|
1073
|
+
return this._findByInternalModel(internalModel, options);
|
|
1069
1074
|
}
|
|
1070
1075
|
|
|
1071
1076
|
let fetchedInternalModel = this._findRecord(internalModel, options);
|
|
@@ -1073,7 +1078,7 @@ abstract class CoreStore extends Service {
|
|
|
1073
1078
|
return promiseRecord(fetchedInternalModel, `DS: Store#findRecord ${internalModel.identifier}`);
|
|
1074
1079
|
}
|
|
1075
1080
|
|
|
1076
|
-
_findRecord(internalModel: InternalModel, options: FindOptions)
|
|
1081
|
+
_findRecord(internalModel: InternalModel, options: FindOptions) {
|
|
1077
1082
|
// Refetch if the reload option is passed
|
|
1078
1083
|
if (options.reload) {
|
|
1079
1084
|
return this._scheduleFetch(internalModel, options);
|
|
@@ -1092,7 +1097,7 @@ abstract class CoreStore extends Service {
|
|
|
1092
1097
|
}
|
|
1093
1098
|
|
|
1094
1099
|
if (options.backgroundReload === false) {
|
|
1095
|
-
return resolve(internalModel);
|
|
1100
|
+
return Promise.resolve(internalModel);
|
|
1096
1101
|
}
|
|
1097
1102
|
|
|
1098
1103
|
// Trigger the background refetch if backgroundReload option is passed
|
|
@@ -1105,20 +1110,25 @@ abstract class CoreStore extends Service {
|
|
|
1105
1110
|
}
|
|
1106
1111
|
|
|
1107
1112
|
// Return the cached record
|
|
1108
|
-
return resolve(internalModel);
|
|
1113
|
+
return Promise.resolve(internalModel);
|
|
1109
1114
|
}
|
|
1110
1115
|
|
|
1111
|
-
_findByInternalModel(internalModel: InternalModel, options: FindOptions = {})
|
|
1116
|
+
_findByInternalModel(internalModel: InternalModel, options: FindOptions = {}) {
|
|
1112
1117
|
if (options.preload) {
|
|
1113
1118
|
this._backburner.join(() => {
|
|
1114
1119
|
internalModel.preloadData(options.preload);
|
|
1115
1120
|
});
|
|
1116
1121
|
}
|
|
1117
1122
|
|
|
1118
|
-
|
|
1123
|
+
let fetchedInternalModel = this._findEmptyInternalModel(internalModel, options);
|
|
1124
|
+
|
|
1125
|
+
return promiseRecord(
|
|
1126
|
+
fetchedInternalModel,
|
|
1127
|
+
`DS: Store#findRecord ${internalModel.modelName} with id: ${internalModel.id}`
|
|
1128
|
+
);
|
|
1119
1129
|
}
|
|
1120
1130
|
|
|
1121
|
-
_findEmptyInternalModel(internalModel: InternalModel, options: FindOptions)
|
|
1131
|
+
_findEmptyInternalModel(internalModel: InternalModel, options: FindOptions) {
|
|
1122
1132
|
if (internalModel.currentState.isEmpty) {
|
|
1123
1133
|
return this._scheduleFetch(internalModel, options);
|
|
1124
1134
|
}
|
|
@@ -1126,12 +1136,12 @@ abstract class CoreStore extends Service {
|
|
|
1126
1136
|
if (internalModel.currentState.isLoading) {
|
|
1127
1137
|
let pendingRequest = this._fetchManager.getPendingFetch(internalModel.identifier, options);
|
|
1128
1138
|
if (pendingRequest) {
|
|
1129
|
-
return pendingRequest.then(() => resolve(internalModel));
|
|
1139
|
+
return pendingRequest.then(() => Promise.resolve(internalModel));
|
|
1130
1140
|
}
|
|
1131
1141
|
return this._scheduleFetch(internalModel, options);
|
|
1132
1142
|
}
|
|
1133
1143
|
|
|
1134
|
-
return resolve(internalModel);
|
|
1144
|
+
return Promise.resolve(internalModel);
|
|
1135
1145
|
}
|
|
1136
1146
|
|
|
1137
1147
|
/**
|
|
@@ -1172,10 +1182,10 @@ abstract class CoreStore extends Service {
|
|
|
1172
1182
|
fetches[i] = this._scheduleFetch(internalModels[i], options);
|
|
1173
1183
|
}
|
|
1174
1184
|
|
|
1175
|
-
return all(fetches);
|
|
1185
|
+
return Promise.all(fetches);
|
|
1176
1186
|
}
|
|
1177
1187
|
|
|
1178
|
-
_scheduleFetch(internalModel: InternalModel, options = {}): Promise<InternalModel> {
|
|
1188
|
+
_scheduleFetch(internalModel: InternalModel, options = {}): RSVP.Promise<InternalModel> {
|
|
1179
1189
|
let generateStackTrace = this.generateStackTracesForTrackedRequests;
|
|
1180
1190
|
// TODO remove this once we don't rely on state machine
|
|
1181
1191
|
internalModel.send('loadingData');
|
|
@@ -1366,7 +1376,7 @@ abstract class CoreStore extends Service {
|
|
|
1366
1376
|
@param options optional to include adapterOptions
|
|
1367
1377
|
@return {Promise} promise
|
|
1368
1378
|
*/
|
|
1369
|
-
_reloadRecord(internalModel
|
|
1379
|
+
_reloadRecord(internalModel, options): RSVP.Promise<InternalModel> {
|
|
1370
1380
|
options.isReloading = true;
|
|
1371
1381
|
let { id, modelName } = internalModel;
|
|
1372
1382
|
let adapter = this.adapterFor(modelName);
|
|
@@ -1375,7 +1385,7 @@ abstract class CoreStore extends Service {
|
|
|
1375
1385
|
assert(`You tried to reload a record but you have no adapter (for ${modelName})`, adapter);
|
|
1376
1386
|
assert(
|
|
1377
1387
|
`You tried to reload a record but your adapter does not implement 'findRecord'`,
|
|
1378
|
-
typeof adapter.findRecord === 'function'
|
|
1388
|
+
typeof adapter.findRecord === 'function' || typeof adapter.find === 'function'
|
|
1379
1389
|
);
|
|
1380
1390
|
|
|
1381
1391
|
return this._scheduleFetch(internalModel, options);
|
|
@@ -1462,7 +1472,7 @@ abstract class CoreStore extends Service {
|
|
|
1462
1472
|
finds[i] = this._findEmptyInternalModel(internalModels[i], options);
|
|
1463
1473
|
}
|
|
1464
1474
|
|
|
1465
|
-
return all(finds);
|
|
1475
|
+
return Promise.all(finds);
|
|
1466
1476
|
}
|
|
1467
1477
|
|
|
1468
1478
|
/**
|
|
@@ -1504,12 +1514,12 @@ abstract class CoreStore extends Service {
|
|
|
1504
1514
|
_findHasManyByJsonApiResource(
|
|
1505
1515
|
resource,
|
|
1506
1516
|
parentInternalModel: InternalModel,
|
|
1507
|
-
relationship: ManyRelationship,
|
|
1508
|
-
options
|
|
1509
|
-
): Promise<
|
|
1517
|
+
relationship: ManyRelationship | BelongsToRelationship,
|
|
1518
|
+
options: any
|
|
1519
|
+
): RSVP.Promise<unknown> {
|
|
1510
1520
|
if (HAS_RECORD_DATA_PACKAGE) {
|
|
1511
1521
|
if (!resource) {
|
|
1512
|
-
return resolve();
|
|
1522
|
+
return resolve([]);
|
|
1513
1523
|
}
|
|
1514
1524
|
const { definition, state } = relationship;
|
|
1515
1525
|
let adapter = this.adapterFor(definition.type);
|
|
@@ -1554,7 +1564,7 @@ abstract class CoreStore extends Service {
|
|
|
1554
1564
|
|
|
1555
1565
|
// we were explicitly told we have no data and no links.
|
|
1556
1566
|
// TODO if the relationshipIsStale, should we hit the adapter anyway?
|
|
1557
|
-
return resolve();
|
|
1567
|
+
return resolve([]);
|
|
1558
1568
|
}
|
|
1559
1569
|
assert(`hasMany only works with the @ember-data/record-data package`);
|
|
1560
1570
|
}
|
|
@@ -1567,7 +1577,7 @@ abstract class CoreStore extends Service {
|
|
|
1567
1577
|
@param {Relationship} relationship
|
|
1568
1578
|
@return {Promise} promise
|
|
1569
1579
|
*/
|
|
1570
|
-
findBelongsTo(internalModel, link, relationship, options)
|
|
1580
|
+
findBelongsTo(internalModel, link, relationship, options) {
|
|
1571
1581
|
if (DEBUG) {
|
|
1572
1582
|
assertDestroyingStore(this, 'findBelongsTo');
|
|
1573
1583
|
}
|
|
@@ -1585,25 +1595,19 @@ abstract class CoreStore extends Service {
|
|
|
1585
1595
|
return _findBelongsTo(adapter, this, internalModel, link, relationship, options);
|
|
1586
1596
|
}
|
|
1587
1597
|
|
|
1588
|
-
_fetchBelongsToLinkFromResource(
|
|
1589
|
-
resource,
|
|
1590
|
-
parentInternalModel: InternalModel,
|
|
1591
|
-
relationshipMeta,
|
|
1592
|
-
options
|
|
1593
|
-
): Promise<InternalModel | null> {
|
|
1598
|
+
_fetchBelongsToLinkFromResource(resource, parentInternalModel, relationshipMeta, options) {
|
|
1594
1599
|
if (!resource || !resource.links || !resource.links.related) {
|
|
1595
1600
|
// should we warn here, not sure cause its an internal method
|
|
1596
1601
|
return resolve(null);
|
|
1597
1602
|
}
|
|
1598
|
-
return this.findBelongsTo(parentInternalModel, resource.links.related, relationshipMeta, options)
|
|
1603
|
+
return this.findBelongsTo(parentInternalModel, resource.links.related, relationshipMeta, options).then(
|
|
1604
|
+
(internalModel) => {
|
|
1605
|
+
return internalModel ? internalModel.getRecord() : null;
|
|
1606
|
+
}
|
|
1607
|
+
);
|
|
1599
1608
|
}
|
|
1600
1609
|
|
|
1601
|
-
_findBelongsToByJsonApiResource(
|
|
1602
|
-
resource,
|
|
1603
|
-
parentInternalModel: InternalModel,
|
|
1604
|
-
relationshipMeta,
|
|
1605
|
-
options
|
|
1606
|
-
): Promise<InternalModel | null> {
|
|
1610
|
+
_findBelongsToByJsonApiResource(resource, parentInternalModel, relationshipMeta, options) {
|
|
1607
1611
|
if (!resource) {
|
|
1608
1612
|
return resolve(null);
|
|
1609
1613
|
}
|
|
@@ -1622,7 +1626,7 @@ abstract class CoreStore extends Service {
|
|
|
1622
1626
|
// short circuit if we are already loading
|
|
1623
1627
|
let pendingRequest = this._fetchManager.getPendingFetch(internalModel.identifier, options);
|
|
1624
1628
|
if (pendingRequest) {
|
|
1625
|
-
return pendingRequest.then(() => internalModel);
|
|
1629
|
+
return pendingRequest.then(() => internalModel.getRecord());
|
|
1626
1630
|
}
|
|
1627
1631
|
}
|
|
1628
1632
|
|
|
@@ -1655,12 +1659,14 @@ abstract class CoreStore extends Service {
|
|
|
1655
1659
|
let resourceIsLocal = !localDataIsEmpty && resource.data.id === null;
|
|
1656
1660
|
|
|
1657
1661
|
if (internalModel && resourceIsLocal) {
|
|
1658
|
-
return resolve(internalModel);
|
|
1662
|
+
return resolve(internalModel.getRecord());
|
|
1659
1663
|
}
|
|
1660
1664
|
|
|
1661
1665
|
// fetch by data
|
|
1662
1666
|
if (internalModel && !localDataIsEmpty) {
|
|
1663
|
-
return this._scheduleFetch(internalModel, options)
|
|
1667
|
+
return this._scheduleFetch(internalModel, options).then(() => {
|
|
1668
|
+
return internalModel.getRecord();
|
|
1669
|
+
});
|
|
1664
1670
|
}
|
|
1665
1671
|
|
|
1666
1672
|
// we were explicitly told we have no data and no links.
|
|
@@ -1719,7 +1725,7 @@ abstract class CoreStore extends Service {
|
|
|
1719
1725
|
@param {Object} options optional, may include `adapterOptions` hash which will be passed to adapter.query
|
|
1720
1726
|
@return {Promise} promise
|
|
1721
1727
|
*/
|
|
1722
|
-
query(modelName: string, query, options): PromiseArray<
|
|
1728
|
+
query(modelName: string, query, options): PromiseArray<DSModel> {
|
|
1723
1729
|
if (DEBUG) {
|
|
1724
1730
|
assertDestroyingStore(this, 'query');
|
|
1725
1731
|
}
|
|
@@ -1737,10 +1743,10 @@ abstract class CoreStore extends Service {
|
|
|
1737
1743
|
}
|
|
1738
1744
|
|
|
1739
1745
|
let normalizedModelName = normalizeModelName(modelName);
|
|
1740
|
-
return
|
|
1746
|
+
return this._query(normalizedModelName, query, null, adapterOptionsWrapper);
|
|
1741
1747
|
}
|
|
1742
1748
|
|
|
1743
|
-
_query(modelName: string, query, array, options):
|
|
1749
|
+
_query(modelName: string, query, array, options): PromiseArray<DSModel> {
|
|
1744
1750
|
assert(`You need to pass a model name to the store's query method`, isPresent(modelName));
|
|
1745
1751
|
assert(`You need to pass a query hash to the store's query method`, query);
|
|
1746
1752
|
assert(
|
|
@@ -1756,7 +1762,7 @@ abstract class CoreStore extends Service {
|
|
|
1756
1762
|
typeof adapter.query === 'function'
|
|
1757
1763
|
);
|
|
1758
1764
|
|
|
1759
|
-
return _query(adapter, this, modelName, query, array, options)
|
|
1765
|
+
return promiseArray(_query(adapter, this, modelName, query, array, options));
|
|
1760
1766
|
}
|
|
1761
1767
|
|
|
1762
1768
|
/**
|
|
@@ -1857,7 +1863,7 @@ abstract class CoreStore extends Service {
|
|
|
1857
1863
|
@param {Object} options optional, may include `adapterOptions` hash which will be passed to adapter.queryRecord
|
|
1858
1864
|
@return {Promise} promise which resolves with the found record or `null`
|
|
1859
1865
|
*/
|
|
1860
|
-
queryRecord(modelName
|
|
1866
|
+
queryRecord(modelName, query, options) {
|
|
1861
1867
|
if (DEBUG) {
|
|
1862
1868
|
assertDestroyingStore(this, 'queryRecord');
|
|
1863
1869
|
}
|
|
@@ -1882,17 +1888,15 @@ abstract class CoreStore extends Service {
|
|
|
1882
1888
|
typeof adapter.queryRecord === 'function'
|
|
1883
1889
|
);
|
|
1884
1890
|
|
|
1885
|
-
const promise: Promise<InternalModel | null> = _queryRecord(
|
|
1886
|
-
adapter,
|
|
1887
|
-
this,
|
|
1888
|
-
normalizedModelName,
|
|
1889
|
-
query,
|
|
1890
|
-
adapterOptionsWrapper
|
|
1891
|
-
) as Promise<InternalModel | null>;
|
|
1892
|
-
|
|
1893
1891
|
return promiseObject(
|
|
1894
|
-
|
|
1895
|
-
|
|
1892
|
+
_queryRecord(adapter, this, normalizedModelName, query, adapterOptionsWrapper).then((internalModel) => {
|
|
1893
|
+
// the promise returned by store.queryRecord is expected to resolve with
|
|
1894
|
+
// an instance of Model
|
|
1895
|
+
if (internalModel) {
|
|
1896
|
+
return internalModel.getRecord();
|
|
1897
|
+
}
|
|
1898
|
+
|
|
1899
|
+
return null;
|
|
1896
1900
|
})
|
|
1897
1901
|
);
|
|
1898
1902
|
}
|
|
@@ -2085,10 +2089,7 @@ abstract class CoreStore extends Service {
|
|
|
2085
2089
|
@param {Object} options
|
|
2086
2090
|
@return {Promise} promise
|
|
2087
2091
|
*/
|
|
2088
|
-
findAll(
|
|
2089
|
-
modelName: string,
|
|
2090
|
-
options: { reload?: boolean; backgroundReload?: boolean } = {}
|
|
2091
|
-
): PromiseArray<RecordInstance, RecordArray> {
|
|
2092
|
+
findAll(modelName, options) {
|
|
2092
2093
|
if (DEBUG) {
|
|
2093
2094
|
assertDestroyingStore(this, 'findAll');
|
|
2094
2095
|
}
|
|
@@ -2101,7 +2102,7 @@ abstract class CoreStore extends Service {
|
|
|
2101
2102
|
let normalizedModelName = normalizeModelName(modelName);
|
|
2102
2103
|
let fetch = this._fetchAll(normalizedModelName, this.peekAll(normalizedModelName), options);
|
|
2103
2104
|
|
|
2104
|
-
return
|
|
2105
|
+
return fetch;
|
|
2105
2106
|
}
|
|
2106
2107
|
|
|
2107
2108
|
/**
|
|
@@ -2111,11 +2112,7 @@ abstract class CoreStore extends Service {
|
|
|
2111
2112
|
@param {RecordArray} array
|
|
2112
2113
|
@return {Promise} promise
|
|
2113
2114
|
*/
|
|
2114
|
-
_fetchAll(
|
|
2115
|
-
modelName: string,
|
|
2116
|
-
array: RecordArray,
|
|
2117
|
-
options: { reload?: boolean; backgroundReload?: boolean }
|
|
2118
|
-
): Promise<RecordArray> {
|
|
2115
|
+
_fetchAll(modelName, array, options: { reload?: boolean; backgroundReload?: boolean } = {}) {
|
|
2119
2116
|
let adapter = this.adapterFor(modelName);
|
|
2120
2117
|
|
|
2121
2118
|
assert(`You tried to load all records but you have no adapter (for ${modelName})`, adapter);
|
|
@@ -2126,7 +2123,7 @@ abstract class CoreStore extends Service {
|
|
|
2126
2123
|
|
|
2127
2124
|
if (options.reload) {
|
|
2128
2125
|
set(array, 'isUpdating', true);
|
|
2129
|
-
return _findAll(adapter, this, modelName, options);
|
|
2126
|
+
return promiseArray(_findAll(adapter, this, modelName, options));
|
|
2130
2127
|
}
|
|
2131
2128
|
|
|
2132
2129
|
let snapshotArray = array._createSnapshot(options);
|
|
@@ -2137,12 +2134,12 @@ abstract class CoreStore extends Service {
|
|
|
2137
2134
|
(!adapter.shouldReloadAll && snapshotArray.length === 0)
|
|
2138
2135
|
) {
|
|
2139
2136
|
set(array, 'isUpdating', true);
|
|
2140
|
-
return _findAll(adapter, this, modelName, options);
|
|
2137
|
+
return promiseArray(_findAll(adapter, this, modelName, options));
|
|
2141
2138
|
}
|
|
2142
2139
|
}
|
|
2143
2140
|
|
|
2144
2141
|
if (options.backgroundReload === false) {
|
|
2145
|
-
return resolve(array);
|
|
2142
|
+
return promiseArray(Promise.resolve(array));
|
|
2146
2143
|
}
|
|
2147
2144
|
|
|
2148
2145
|
if (
|
|
@@ -2154,7 +2151,7 @@ abstract class CoreStore extends Service {
|
|
|
2154
2151
|
_findAll(adapter, this, modelName, options);
|
|
2155
2152
|
}
|
|
2156
2153
|
|
|
2157
|
-
return resolve(array);
|
|
2154
|
+
return promiseArray(Promise.resolve(array));
|
|
2158
2155
|
}
|
|
2159
2156
|
|
|
2160
2157
|
/**
|
|
@@ -2162,7 +2159,7 @@ abstract class CoreStore extends Service {
|
|
|
2162
2159
|
@param {String} modelName
|
|
2163
2160
|
@private
|
|
2164
2161
|
*/
|
|
2165
|
-
_didUpdateAll(modelName
|
|
2162
|
+
_didUpdateAll(modelName) {
|
|
2166
2163
|
this.recordArrayManager._didUpdateAll(modelName);
|
|
2167
2164
|
}
|
|
2168
2165
|
|
|
@@ -2261,11 +2258,7 @@ abstract class CoreStore extends Service {
|
|
|
2261
2258
|
@param {Resolver} resolver
|
|
2262
2259
|
@param {Object} options
|
|
2263
2260
|
*/
|
|
2264
|
-
scheduleSave(
|
|
2265
|
-
internalModel: InternalModel,
|
|
2266
|
-
resolver: RSVP.Deferred<void>,
|
|
2267
|
-
options: FindOptions
|
|
2268
|
-
): void | Promise<void> {
|
|
2261
|
+
scheduleSave(internalModel: InternalModel, resolver: RSVP.Deferred<void>, options): void | RSVP.Promise<void> {
|
|
2269
2262
|
if (internalModel._isRecordFullyDeleted()) {
|
|
2270
2263
|
resolver.resolve();
|
|
2271
2264
|
return resolver.promise;
|
|
@@ -2286,8 +2279,9 @@ abstract class CoreStore extends Service {
|
|
|
2286
2279
|
operation = 'deleteRecord';
|
|
2287
2280
|
}
|
|
2288
2281
|
|
|
2289
|
-
|
|
2290
|
-
|
|
2282
|
+
options[SaveOp] = operation;
|
|
2283
|
+
|
|
2284
|
+
let fetchManagerPromise = this._fetchManager.scheduleSave(internalModel.identifier, options);
|
|
2291
2285
|
let promise = fetchManagerPromise.then(
|
|
2292
2286
|
(payload) => {
|
|
2293
2287
|
/*
|
|
@@ -2828,6 +2822,10 @@ abstract class CoreStore extends Service {
|
|
|
2828
2822
|
serializer.pushPayload(this, payload);
|
|
2829
2823
|
}
|
|
2830
2824
|
|
|
2825
|
+
reloadManyArray(manyArray, internalModel, key, options) {
|
|
2826
|
+
return internalModel.reloadHasMany(key, options);
|
|
2827
|
+
}
|
|
2828
|
+
|
|
2831
2829
|
reloadBelongsTo(belongsToProxy, internalModel, key, options) {
|
|
2832
2830
|
return internalModel.reloadBelongsTo(key, options);
|
|
2833
2831
|
}
|
|
@@ -2854,13 +2852,13 @@ abstract class CoreStore extends Service {
|
|
|
2854
2852
|
return internalModel!.createSnapshot(options).serialize(options);
|
|
2855
2853
|
}
|
|
2856
2854
|
|
|
2857
|
-
saveRecord(record: RecordInstance, options?: Dict<unknown>): Promise<RecordInstance> {
|
|
2855
|
+
saveRecord(record: RecordInstance, options?: Dict<unknown>): RSVP.Promise<RecordInstance> {
|
|
2858
2856
|
let identifier = recordIdentifierFor(record);
|
|
2859
2857
|
let internalModel = internalModelFactoryFor(this).peek(identifier);
|
|
2860
2858
|
// TODO we used to check if the record was destroyed here
|
|
2861
2859
|
// Casting can be removed once REQUEST_SERVICE ff is turned on
|
|
2862
2860
|
// because a `Record` is provided there will always be a matching internalModel
|
|
2863
|
-
return (internalModel!.save(options) as Promise<void>).then(() => record);
|
|
2861
|
+
return (internalModel!.save(options) as RSVP.Promise<void>).then(() => record);
|
|
2864
2862
|
}
|
|
2865
2863
|
|
|
2866
2864
|
relationshipReferenceFor(identifier: RecordIdentifier, key: string): BelongsToReference | HasManyReference {
|
|
@@ -2910,9 +2908,7 @@ abstract class CoreStore extends Service {
|
|
|
2910
2908
|
// it can be reproduced in partner tests by running
|
|
2911
2909
|
// node ./scripts/packages-for-commit.js && yarn test-external:ember-observer
|
|
2912
2910
|
if (_RecordData === undefined) {
|
|
2913
|
-
_RecordData = (
|
|
2914
|
-
importSync('@ember-data/record-data/-private') as typeof import('@ember-data/record-data/-private')
|
|
2915
|
-
).RecordData as RecordDataConstruct;
|
|
2911
|
+
_RecordData = require('@ember-data/record-data/-private').RecordData as RecordDataConstruct;
|
|
2916
2912
|
}
|
|
2917
2913
|
|
|
2918
2914
|
let identifier = this.identifierCache.getOrCreateRecordIdentifier({
|
|
@@ -2970,7 +2966,7 @@ abstract class CoreStore extends Service {
|
|
|
2970
2966
|
@param {Object} payload
|
|
2971
2967
|
@return {Object} The normalized payload
|
|
2972
2968
|
*/
|
|
2973
|
-
normalize(modelName
|
|
2969
|
+
normalize(modelName, payload) {
|
|
2974
2970
|
if (DEBUG) {
|
|
2975
2971
|
assertDestroyingStore(this, 'normalize');
|
|
2976
2972
|
}
|
|
@@ -2986,7 +2982,7 @@ abstract class CoreStore extends Service {
|
|
|
2986
2982
|
let model = this.modelFor(normalizedModelName);
|
|
2987
2983
|
assert(
|
|
2988
2984
|
`You must define a normalize method in your serializer in order to call store.normalize`,
|
|
2989
|
-
serializer
|
|
2985
|
+
serializer.normalize
|
|
2990
2986
|
);
|
|
2991
2987
|
return serializer.normalize(model, payload);
|
|
2992
2988
|
}
|
|
@@ -3100,7 +3096,7 @@ abstract class CoreStore extends Service {
|
|
|
3100
3096
|
@param {String} modelName the record to serialize
|
|
3101
3097
|
@return {Serializer}
|
|
3102
3098
|
*/
|
|
3103
|
-
serializerFor(modelName
|
|
3099
|
+
serializerFor(modelName) {
|
|
3104
3100
|
if (DEBUG) {
|
|
3105
3101
|
assertDestroyingStore(this, 'serializerFor');
|
|
3106
3102
|
}
|
|
@@ -3136,29 +3132,30 @@ abstract class CoreStore extends Service {
|
|
|
3136
3132
|
return serializer;
|
|
3137
3133
|
}
|
|
3138
3134
|
|
|
3139
|
-
|
|
3135
|
+
assert(
|
|
3136
|
+
`No serializer was found for '${modelName}' and no 'application' serializer was found as a fallback`,
|
|
3137
|
+
serializer !== undefined
|
|
3138
|
+
);
|
|
3140
3139
|
}
|
|
3141
3140
|
|
|
3142
3141
|
destroy() {
|
|
3143
3142
|
// enqueue destruction of any adapters/serializers we have created
|
|
3144
3143
|
for (let adapterName in this._adapterCache) {
|
|
3145
|
-
let adapter = this._adapterCache[adapterName]
|
|
3144
|
+
let adapter = this._adapterCache[adapterName];
|
|
3146
3145
|
if (typeof adapter.destroy === 'function') {
|
|
3147
3146
|
adapter.destroy();
|
|
3148
3147
|
}
|
|
3149
3148
|
}
|
|
3150
3149
|
|
|
3151
3150
|
for (let serializerName in this._serializerCache) {
|
|
3152
|
-
let serializer = this._serializerCache[serializerName]
|
|
3151
|
+
let serializer = this._serializerCache[serializerName];
|
|
3153
3152
|
if (typeof serializer.destroy === 'function') {
|
|
3154
3153
|
serializer.destroy();
|
|
3155
3154
|
}
|
|
3156
3155
|
}
|
|
3157
3156
|
|
|
3158
3157
|
if (HAS_RECORD_DATA_PACKAGE) {
|
|
3159
|
-
const peekGraph = (
|
|
3160
|
-
importSync('@ember-data/record-data/-private') as typeof import('@ember-data/record-data/-private')
|
|
3161
|
-
).peekGraph;
|
|
3158
|
+
const peekGraph = require('@ember-data/record-data/-private').peekGraph;
|
|
3162
3159
|
let graph = peekGraph(this);
|
|
3163
3160
|
if (graph) {
|
|
3164
3161
|
graph.destroy();
|
|
@@ -3178,9 +3175,7 @@ abstract class CoreStore extends Service {
|
|
|
3178
3175
|
// since then we avoid churning relationships
|
|
3179
3176
|
// during unload
|
|
3180
3177
|
if (HAS_RECORD_DATA_PACKAGE) {
|
|
3181
|
-
const peekGraph = (
|
|
3182
|
-
importSync('@ember-data/record-data/-private') as typeof import('@ember-data/record-data/-private')
|
|
3183
|
-
).peekGraph;
|
|
3178
|
+
const peekGraph = require('@ember-data/record-data/-private').peekGraph;
|
|
3184
3179
|
let graph = peekGraph(this);
|
|
3185
3180
|
if (graph) {
|
|
3186
3181
|
graph.willDestroy();
|
|
@@ -3214,6 +3209,24 @@ abstract class CoreStore extends Service {
|
|
|
3214
3209
|
}
|
|
3215
3210
|
}
|
|
3216
3211
|
}
|
|
3212
|
+
|
|
3213
|
+
_updateInternalModel(internalModel: InternalModel) {
|
|
3214
|
+
if (this._updatedInternalModels.push(internalModel) !== 1) {
|
|
3215
|
+
return;
|
|
3216
|
+
}
|
|
3217
|
+
|
|
3218
|
+
emberBackburner.schedule('actions', this, this._flushUpdatedInternalModels);
|
|
3219
|
+
}
|
|
3220
|
+
|
|
3221
|
+
_flushUpdatedInternalModels() {
|
|
3222
|
+
let updated = this._updatedInternalModels;
|
|
3223
|
+
|
|
3224
|
+
for (let i = 0, l = updated.length; i < l; i++) {
|
|
3225
|
+
updated[i]._triggerDeferredTriggers();
|
|
3226
|
+
}
|
|
3227
|
+
|
|
3228
|
+
updated.length = 0;
|
|
3229
|
+
}
|
|
3217
3230
|
}
|
|
3218
3231
|
|
|
3219
3232
|
export default CoreStore;
|