@ember-data/store 4.4.0-alpha.5 → 4.4.0-alpha.8
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 +130 -119
- package/addon/-private/system/ds-model-store.ts +1 -10
- package/addon/-private/system/fetch-manager.ts +48 -21
- package/addon/-private/system/model/internal-model.ts +264 -160
- package/addon/-private/system/{promise-proxies.js → promise-proxies.ts} +31 -21
- package/addon/-private/system/promise-proxy-base.js +7 -0
- package/addon/-private/system/{record-array-manager.js → record-array-manager.ts} +87 -60
- package/addon/-private/system/record-arrays/adapter-populated-record-array.ts +129 -0
- package/addon/-private/system/record-arrays/{record-array.js → record-array.ts} +96 -75
- package/addon/-private/system/record-data-for.ts +2 -0
- package/addon/-private/system/references/belongs-to.ts +3 -2
- package/addon/-private/system/references/has-many.ts +4 -2
- package/addon/-private/system/schema-definition-service.ts +2 -2
- package/addon/-private/system/snapshot-record-array.ts +12 -11
- package/addon/-private/system/snapshot.ts +24 -7
- package/addon/-private/system/store/common.js +24 -1
- package/addon/-private/system/store/finders.js +53 -5
- package/addon/-private/system/store/internal-model-factory.ts +8 -7
- package/addon/-private/system/store/record-data-store-wrapper.ts +7 -2
- package/addon/-private/system/store/serializer-response.ts +85 -0
- package/addon/-private/ts-interfaces/ds-model.ts +15 -7
- package/addon/-private/ts-interfaces/ember-data-json-api.ts +3 -0
- package/addon/-private/ts-interfaces/minimum-adapter-interface.ts +19 -20
- package/addon/-private/ts-interfaces/minimum-serializer-interface.ts +27 -6
- package/addon/-private/ts-interfaces/record-data.ts +4 -1
- package/addon/-private/ts-interfaces/record-instance.ts +3 -1
- package/addon/-private/ts-interfaces/store.ts +1 -0
- package/addon/-private/utils/promise-record.ts +3 -3
- package/index.js +3 -0
- package/package.json +6 -5
- package/addon/-private/system/record-arrays/adapter-populated-record-array.js +0 -95
- package/addon/-private/system/store/serializer-response.js +0 -71
|
@@ -13,19 +13,14 @@ 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,
|
|
16
|
+
import { importSync } from '@embroider/macros';
|
|
17
|
+
import { all, default as RSVP, resolve } from 'rsvp';
|
|
18
18
|
|
|
19
19
|
import { HAS_RECORD_DATA_PACKAGE } from '@ember-data/private-build-infra';
|
|
20
|
-
import type {
|
|
21
|
-
BelongsToRelationship,
|
|
22
|
-
ManyRelationship,
|
|
23
|
-
RecordData as RecordDataClass,
|
|
24
|
-
} from '@ember-data/record-data/-private';
|
|
20
|
+
import type { ManyRelationship, RecordData as RecordDataClass } from '@ember-data/record-data/-private';
|
|
25
21
|
import type { RelationshipState } from '@ember-data/record-data/-private/graph/-state';
|
|
26
22
|
|
|
27
23
|
import { IdentifierCache } from '../identifiers/cache';
|
|
28
|
-
import type { DSModel } from '../ts-interfaces/ds-model';
|
|
29
24
|
import type {
|
|
30
25
|
CollectionResourceDocument,
|
|
31
26
|
EmptyResourceDocument,
|
|
@@ -39,11 +34,12 @@ import type {
|
|
|
39
34
|
StableExistingRecordIdentifier,
|
|
40
35
|
StableRecordIdentifier,
|
|
41
36
|
} from '../ts-interfaces/identifier';
|
|
42
|
-
import
|
|
37
|
+
import { MinimumAdapterInterface } from '../ts-interfaces/minimum-adapter-interface';
|
|
38
|
+
import type { MinimumSerializerInterface } from '../ts-interfaces/minimum-serializer-interface';
|
|
43
39
|
import type { RecordData } from '../ts-interfaces/record-data';
|
|
44
40
|
import type { JsonApiRelationship } from '../ts-interfaces/record-data-json-api';
|
|
45
41
|
import type { RecordDataRecordWrapper } from '../ts-interfaces/record-data-record-wrapper';
|
|
46
|
-
import type { AttributesSchema } from '../ts-interfaces/record-data-schemas';
|
|
42
|
+
import type { AttributesSchema, RelationshipsSchema } from '../ts-interfaces/record-data-schemas';
|
|
47
43
|
import type { RecordInstance } from '../ts-interfaces/record-instance';
|
|
48
44
|
import type { SchemaDefinitionService } from '../ts-interfaces/schema-definition-service';
|
|
49
45
|
import type { FindOptions } from '../ts-interfaces/store';
|
|
@@ -62,8 +58,10 @@ import {
|
|
|
62
58
|
import type ShimModelClass from './model/shim-model-class';
|
|
63
59
|
import { getShimClass } from './model/shim-model-class';
|
|
64
60
|
import normalizeModelName from './normalize-model-name';
|
|
61
|
+
import type { PromiseArray, PromiseObject } from './promise-proxies';
|
|
65
62
|
import { promiseArray, promiseObject } from './promise-proxies';
|
|
66
63
|
import RecordArrayManager from './record-array-manager';
|
|
64
|
+
import { AdapterPopulatedRecordArray, RecordArray } from './record-arrays';
|
|
67
65
|
import { setRecordDataFor } from './record-data-for';
|
|
68
66
|
import NotificationManager from './record-notification-manager';
|
|
69
67
|
import type { BelongsToReference, HasManyReference } from './references';
|
|
@@ -84,7 +82,6 @@ let _RecordData: RecordDataConstruct | undefined;
|
|
|
84
82
|
|
|
85
83
|
const { ENV } = Ember;
|
|
86
84
|
type AsyncTrackingToken = Readonly<{ label: string; trace: Error | string }>;
|
|
87
|
-
type PromiseArray<T> = Promise<T[]>;
|
|
88
85
|
|
|
89
86
|
const RECORD_REFERENCES = new WeakCache<StableRecordIdentifier, RecordReference>(DEBUG ? 'reference' : '');
|
|
90
87
|
|
|
@@ -96,6 +93,11 @@ function freeze<T>(obj: T): T {
|
|
|
96
93
|
return obj;
|
|
97
94
|
}
|
|
98
95
|
|
|
96
|
+
export interface CreateRecordProperties {
|
|
97
|
+
id?: string | null;
|
|
98
|
+
[key: string]: unknown;
|
|
99
|
+
}
|
|
100
|
+
|
|
99
101
|
/**
|
|
100
102
|
The store contains all of the data for records loaded from the server.
|
|
101
103
|
It is also responsible for creating instances of `Model` that wrap
|
|
@@ -176,14 +178,14 @@ abstract class CoreStore extends Service {
|
|
|
176
178
|
* @property _backburner
|
|
177
179
|
* @private
|
|
178
180
|
*/
|
|
179
|
-
|
|
180
|
-
|
|
181
|
+
declare _backburner: Backburner;
|
|
182
|
+
declare recordArrayManager: RecordArrayManager;
|
|
181
183
|
|
|
182
184
|
declare _notificationManager: NotificationManager;
|
|
183
185
|
declare identifierCache: IdentifierCache;
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
186
|
+
declare _adapterCache: Dict<MinimumAdapterInterface & { store: CoreStore }>;
|
|
187
|
+
declare _serializerCache: Dict<MinimumSerializerInterface & { store: CoreStore }>;
|
|
188
|
+
declare _storeWrapper: RecordDataStoreWrapper;
|
|
187
189
|
|
|
188
190
|
/*
|
|
189
191
|
Ember Data uses several specialized micro-queues for organizing
|
|
@@ -193,15 +195,15 @@ abstract class CoreStore extends Service {
|
|
|
193
195
|
ember-data's custom backburner instance.
|
|
194
196
|
*/
|
|
195
197
|
// used for coalescing internal model updates
|
|
196
|
-
|
|
198
|
+
declare _updatedInternalModels: InternalModel[];
|
|
197
199
|
|
|
198
200
|
declare _fetchManager: FetchManager;
|
|
199
201
|
declare _schemaDefinitionService: SchemaDefinitionService;
|
|
200
202
|
|
|
201
203
|
// DEBUG-only properties
|
|
202
204
|
declare _trackedAsyncRequests: AsyncTrackingToken[];
|
|
203
|
-
shouldTrackAsyncRequests: boolean
|
|
204
|
-
generateStackTracesForTrackedRequests: boolean
|
|
205
|
+
declare shouldTrackAsyncRequests: boolean;
|
|
206
|
+
declare generateStackTracesForTrackedRequests: boolean;
|
|
205
207
|
declare _trackAsyncRequestStart: (str: string) => void;
|
|
206
208
|
declare _trackAsyncRequestEnd: (token: AsyncTrackingToken) => void;
|
|
207
209
|
declare __asyncWaiter: () => boolean;
|
|
@@ -252,6 +254,12 @@ abstract class CoreStore extends Service {
|
|
|
252
254
|
*/
|
|
253
255
|
constructor() {
|
|
254
256
|
super(...arguments);
|
|
257
|
+
this._adapterCache = Object.create(null);
|
|
258
|
+
this._serializerCache = Object.create(null);
|
|
259
|
+
this._storeWrapper = new RecordDataStoreWrapper(this);
|
|
260
|
+
this._backburner = edBackburner;
|
|
261
|
+
this.recordArrayManager = new RecordArrayManager({ store: this });
|
|
262
|
+
this._updatedInternalModels = [];
|
|
255
263
|
|
|
256
264
|
RECORD_REFERENCES._generator = (identifier) => {
|
|
257
265
|
return new RecordReference(this, identifier);
|
|
@@ -390,19 +398,14 @@ abstract class CoreStore extends Service {
|
|
|
390
398
|
recordDataFor: (identifier: RecordIdentifier) => RecordDataRecordWrapper,
|
|
391
399
|
notificationManager: NotificationManager
|
|
392
400
|
): RecordInstance;
|
|
393
|
-
|
|
394
401
|
abstract teardownRecord(record: RecordInstance): void;
|
|
402
|
+
abstract getSchemaDefinitionService(): SchemaDefinitionService;
|
|
395
403
|
|
|
396
|
-
_internalDeleteRecord(internalModel: InternalModel) {
|
|
397
|
-
internalModel.deleteRecord();
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
// FeatureFlagged in the DSModelStore claas
|
|
401
404
|
_attributesDefinitionFor(identifier: RecordIdentifier | { type: string }): AttributesSchema {
|
|
402
405
|
return this.getSchemaDefinitionService().attributesDefinitionFor(identifier);
|
|
403
406
|
}
|
|
404
407
|
|
|
405
|
-
_relationshipsDefinitionFor(identifier: RecordIdentifier | { type: string }) {
|
|
408
|
+
_relationshipsDefinitionFor(identifier: RecordIdentifier | { type: string }): RelationshipsSchema {
|
|
406
409
|
return this.getSchemaDefinitionService().relationshipsDefinitionFor(identifier);
|
|
407
410
|
}
|
|
408
411
|
|
|
@@ -410,11 +413,6 @@ abstract class CoreStore extends Service {
|
|
|
410
413
|
this._schemaDefinitionService = schema;
|
|
411
414
|
}
|
|
412
415
|
|
|
413
|
-
getSchemaDefinitionService(): SchemaDefinitionService {
|
|
414
|
-
return this._schemaDefinitionService;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
// TODO Double check this return value is correct
|
|
418
416
|
_relationshipMetaFor(modelName: string, id: string | null, key: string) {
|
|
419
417
|
return this._relationshipsDefinitionFor({ type: modelName })[key];
|
|
420
418
|
}
|
|
@@ -499,7 +497,7 @@ abstract class CoreStore extends Service {
|
|
|
499
497
|
newly created record.
|
|
500
498
|
@return {Model} record
|
|
501
499
|
*/
|
|
502
|
-
createRecord(modelName, inputProperties) {
|
|
500
|
+
createRecord(modelName: string, inputProperties: CreateRecordProperties): RecordInstance {
|
|
503
501
|
if (DEBUG) {
|
|
504
502
|
assertDestroyingStore(this, 'createRecord');
|
|
505
503
|
}
|
|
@@ -553,7 +551,7 @@ abstract class CoreStore extends Service {
|
|
|
553
551
|
@param {Object} properties from the new record
|
|
554
552
|
@return {String} if the adapter can generate one, an ID
|
|
555
553
|
*/
|
|
556
|
-
_generateId(modelName, properties) {
|
|
554
|
+
_generateId(modelName: string, properties: CreateRecordProperties): string | null {
|
|
557
555
|
let adapter = this.adapterFor(modelName);
|
|
558
556
|
|
|
559
557
|
if (adapter && adapter.generateIdForRecord) {
|
|
@@ -584,7 +582,7 @@ abstract class CoreStore extends Service {
|
|
|
584
582
|
@public
|
|
585
583
|
@param {Model} record
|
|
586
584
|
*/
|
|
587
|
-
deleteRecord(record) {
|
|
585
|
+
deleteRecord(record: RecordInstance): void {
|
|
588
586
|
if (DEBUG) {
|
|
589
587
|
assertDestroyingStore(this, 'deleteRecord');
|
|
590
588
|
}
|
|
@@ -615,7 +613,7 @@ abstract class CoreStore extends Service {
|
|
|
615
613
|
@public
|
|
616
614
|
@param {Model} record
|
|
617
615
|
*/
|
|
618
|
-
unloadRecord(record) {
|
|
616
|
+
unloadRecord(record: RecordInstance): void {
|
|
619
617
|
if (DEBUG) {
|
|
620
618
|
assertDestroyingStore(this, 'unloadRecord');
|
|
621
619
|
}
|
|
@@ -640,7 +638,7 @@ abstract class CoreStore extends Service {
|
|
|
640
638
|
@return {Promise} promise
|
|
641
639
|
@private
|
|
642
640
|
*/
|
|
643
|
-
find(modelName, id, options) {
|
|
641
|
+
find(modelName: string, id: string | number, options?): PromiseObject<RecordInstance> {
|
|
644
642
|
if (DEBUG) {
|
|
645
643
|
assertDestroyingStore(this, 'find');
|
|
646
644
|
}
|
|
@@ -1039,13 +1037,13 @@ abstract class CoreStore extends Service {
|
|
|
1039
1037
|
@param {Object} [options] - if the first param is a string this will be the optional options for the request. See examples for available options.
|
|
1040
1038
|
@return {Promise} promise
|
|
1041
1039
|
*/
|
|
1042
|
-
findRecord(resource: string, id: string | number, options?: FindOptions):
|
|
1043
|
-
findRecord(resource: ResourceIdentifierObject, id?: FindOptions):
|
|
1040
|
+
findRecord(resource: string, id: string | number, options?: FindOptions): PromiseObject<RecordInstance>;
|
|
1041
|
+
findRecord(resource: ResourceIdentifierObject, id?: FindOptions): PromiseObject<RecordInstance>;
|
|
1044
1042
|
findRecord(
|
|
1045
1043
|
resource: string | ResourceIdentifierObject,
|
|
1046
1044
|
id?: string | number | FindOptions,
|
|
1047
1045
|
options?: FindOptions
|
|
1048
|
-
):
|
|
1046
|
+
): PromiseObject<RecordInstance> {
|
|
1049
1047
|
if (DEBUG) {
|
|
1050
1048
|
assertDestroyingStore(this, 'findRecord');
|
|
1051
1049
|
}
|
|
@@ -1070,7 +1068,10 @@ abstract class CoreStore extends Service {
|
|
|
1070
1068
|
options = options || {};
|
|
1071
1069
|
|
|
1072
1070
|
if (!internalModel.currentState.isLoaded) {
|
|
1073
|
-
return
|
|
1071
|
+
return promiseRecord(
|
|
1072
|
+
this._findByInternalModel(internalModel, options),
|
|
1073
|
+
`DS: Store#findRecord ${internalModel.identifier}`
|
|
1074
|
+
);
|
|
1074
1075
|
}
|
|
1075
1076
|
|
|
1076
1077
|
let fetchedInternalModel = this._findRecord(internalModel, options);
|
|
@@ -1078,7 +1079,7 @@ abstract class CoreStore extends Service {
|
|
|
1078
1079
|
return promiseRecord(fetchedInternalModel, `DS: Store#findRecord ${internalModel.identifier}`);
|
|
1079
1080
|
}
|
|
1080
1081
|
|
|
1081
|
-
_findRecord(internalModel: InternalModel, options: FindOptions) {
|
|
1082
|
+
_findRecord(internalModel: InternalModel, options: FindOptions): Promise<InternalModel> {
|
|
1082
1083
|
// Refetch if the reload option is passed
|
|
1083
1084
|
if (options.reload) {
|
|
1084
1085
|
return this._scheduleFetch(internalModel, options);
|
|
@@ -1097,7 +1098,7 @@ abstract class CoreStore extends Service {
|
|
|
1097
1098
|
}
|
|
1098
1099
|
|
|
1099
1100
|
if (options.backgroundReload === false) {
|
|
1100
|
-
return
|
|
1101
|
+
return resolve(internalModel);
|
|
1101
1102
|
}
|
|
1102
1103
|
|
|
1103
1104
|
// Trigger the background refetch if backgroundReload option is passed
|
|
@@ -1110,25 +1111,20 @@ abstract class CoreStore extends Service {
|
|
|
1110
1111
|
}
|
|
1111
1112
|
|
|
1112
1113
|
// Return the cached record
|
|
1113
|
-
return
|
|
1114
|
+
return resolve(internalModel);
|
|
1114
1115
|
}
|
|
1115
1116
|
|
|
1116
|
-
_findByInternalModel(internalModel: InternalModel, options: FindOptions = {}) {
|
|
1117
|
+
_findByInternalModel(internalModel: InternalModel, options: FindOptions = {}): Promise<InternalModel> {
|
|
1117
1118
|
if (options.preload) {
|
|
1118
1119
|
this._backburner.join(() => {
|
|
1119
1120
|
internalModel.preloadData(options.preload);
|
|
1120
1121
|
});
|
|
1121
1122
|
}
|
|
1122
1123
|
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
return promiseRecord(
|
|
1126
|
-
fetchedInternalModel,
|
|
1127
|
-
`DS: Store#findRecord ${internalModel.modelName} with id: ${internalModel.id}`
|
|
1128
|
-
);
|
|
1124
|
+
return this._findEmptyInternalModel(internalModel, options);
|
|
1129
1125
|
}
|
|
1130
1126
|
|
|
1131
|
-
_findEmptyInternalModel(internalModel: InternalModel, options: FindOptions) {
|
|
1127
|
+
_findEmptyInternalModel(internalModel: InternalModel, options: FindOptions): Promise<InternalModel> {
|
|
1132
1128
|
if (internalModel.currentState.isEmpty) {
|
|
1133
1129
|
return this._scheduleFetch(internalModel, options);
|
|
1134
1130
|
}
|
|
@@ -1136,12 +1132,12 @@ abstract class CoreStore extends Service {
|
|
|
1136
1132
|
if (internalModel.currentState.isLoading) {
|
|
1137
1133
|
let pendingRequest = this._fetchManager.getPendingFetch(internalModel.identifier, options);
|
|
1138
1134
|
if (pendingRequest) {
|
|
1139
|
-
return pendingRequest.then(() =>
|
|
1135
|
+
return pendingRequest.then(() => resolve(internalModel));
|
|
1140
1136
|
}
|
|
1141
1137
|
return this._scheduleFetch(internalModel, options);
|
|
1142
1138
|
}
|
|
1143
1139
|
|
|
1144
|
-
return
|
|
1140
|
+
return resolve(internalModel);
|
|
1145
1141
|
}
|
|
1146
1142
|
|
|
1147
1143
|
/**
|
|
@@ -1182,10 +1178,10 @@ abstract class CoreStore extends Service {
|
|
|
1182
1178
|
fetches[i] = this._scheduleFetch(internalModels[i], options);
|
|
1183
1179
|
}
|
|
1184
1180
|
|
|
1185
|
-
return
|
|
1181
|
+
return all(fetches);
|
|
1186
1182
|
}
|
|
1187
1183
|
|
|
1188
|
-
_scheduleFetch(internalModel: InternalModel, options = {}):
|
|
1184
|
+
_scheduleFetch(internalModel: InternalModel, options = {}): Promise<InternalModel> {
|
|
1189
1185
|
let generateStackTrace = this.generateStackTracesForTrackedRequests;
|
|
1190
1186
|
// TODO remove this once we don't rely on state machine
|
|
1191
1187
|
internalModel.send('loadingData');
|
|
@@ -1376,7 +1372,7 @@ abstract class CoreStore extends Service {
|
|
|
1376
1372
|
@param options optional to include adapterOptions
|
|
1377
1373
|
@return {Promise} promise
|
|
1378
1374
|
*/
|
|
1379
|
-
_reloadRecord(internalModel, options):
|
|
1375
|
+
_reloadRecord(internalModel: InternalModel, options: FindOptions): Promise<InternalModel> {
|
|
1380
1376
|
options.isReloading = true;
|
|
1381
1377
|
let { id, modelName } = internalModel;
|
|
1382
1378
|
let adapter = this.adapterFor(modelName);
|
|
@@ -1385,7 +1381,7 @@ abstract class CoreStore extends Service {
|
|
|
1385
1381
|
assert(`You tried to reload a record but you have no adapter (for ${modelName})`, adapter);
|
|
1386
1382
|
assert(
|
|
1387
1383
|
`You tried to reload a record but your adapter does not implement 'findRecord'`,
|
|
1388
|
-
typeof adapter.findRecord === 'function'
|
|
1384
|
+
typeof adapter.findRecord === 'function'
|
|
1389
1385
|
);
|
|
1390
1386
|
|
|
1391
1387
|
return this._scheduleFetch(internalModel, options);
|
|
@@ -1472,7 +1468,7 @@ abstract class CoreStore extends Service {
|
|
|
1472
1468
|
finds[i] = this._findEmptyInternalModel(internalModels[i], options);
|
|
1473
1469
|
}
|
|
1474
1470
|
|
|
1475
|
-
return
|
|
1471
|
+
return all(finds);
|
|
1476
1472
|
}
|
|
1477
1473
|
|
|
1478
1474
|
/**
|
|
@@ -1514,12 +1510,12 @@ abstract class CoreStore extends Service {
|
|
|
1514
1510
|
_findHasManyByJsonApiResource(
|
|
1515
1511
|
resource,
|
|
1516
1512
|
parentInternalModel: InternalModel,
|
|
1517
|
-
relationship: ManyRelationship
|
|
1518
|
-
options
|
|
1519
|
-
):
|
|
1513
|
+
relationship: ManyRelationship,
|
|
1514
|
+
options?: Dict<unknown>
|
|
1515
|
+
): Promise<void | unknown[]> {
|
|
1520
1516
|
if (HAS_RECORD_DATA_PACKAGE) {
|
|
1521
1517
|
if (!resource) {
|
|
1522
|
-
return resolve(
|
|
1518
|
+
return resolve();
|
|
1523
1519
|
}
|
|
1524
1520
|
const { definition, state } = relationship;
|
|
1525
1521
|
let adapter = this.adapterFor(definition.type);
|
|
@@ -1564,7 +1560,7 @@ abstract class CoreStore extends Service {
|
|
|
1564
1560
|
|
|
1565
1561
|
// we were explicitly told we have no data and no links.
|
|
1566
1562
|
// TODO if the relationshipIsStale, should we hit the adapter anyway?
|
|
1567
|
-
return resolve(
|
|
1563
|
+
return resolve();
|
|
1568
1564
|
}
|
|
1569
1565
|
assert(`hasMany only works with the @ember-data/record-data package`);
|
|
1570
1566
|
}
|
|
@@ -1577,7 +1573,7 @@ abstract class CoreStore extends Service {
|
|
|
1577
1573
|
@param {Relationship} relationship
|
|
1578
1574
|
@return {Promise} promise
|
|
1579
1575
|
*/
|
|
1580
|
-
findBelongsTo(internalModel, link, relationship, options) {
|
|
1576
|
+
findBelongsTo(internalModel, link, relationship, options): Promise<InternalModel> {
|
|
1581
1577
|
if (DEBUG) {
|
|
1582
1578
|
assertDestroyingStore(this, 'findBelongsTo');
|
|
1583
1579
|
}
|
|
@@ -1595,19 +1591,25 @@ abstract class CoreStore extends Service {
|
|
|
1595
1591
|
return _findBelongsTo(adapter, this, internalModel, link, relationship, options);
|
|
1596
1592
|
}
|
|
1597
1593
|
|
|
1598
|
-
_fetchBelongsToLinkFromResource(
|
|
1594
|
+
_fetchBelongsToLinkFromResource(
|
|
1595
|
+
resource,
|
|
1596
|
+
parentInternalModel: InternalModel,
|
|
1597
|
+
relationshipMeta,
|
|
1598
|
+
options
|
|
1599
|
+
): Promise<InternalModel | null> {
|
|
1599
1600
|
if (!resource || !resource.links || !resource.links.related) {
|
|
1600
1601
|
// should we warn here, not sure cause its an internal method
|
|
1601
1602
|
return resolve(null);
|
|
1602
1603
|
}
|
|
1603
|
-
return this.findBelongsTo(parentInternalModel, resource.links.related, relationshipMeta, options)
|
|
1604
|
-
(internalModel) => {
|
|
1605
|
-
return internalModel ? internalModel.getRecord() : null;
|
|
1606
|
-
}
|
|
1607
|
-
);
|
|
1604
|
+
return this.findBelongsTo(parentInternalModel, resource.links.related, relationshipMeta, options);
|
|
1608
1605
|
}
|
|
1609
1606
|
|
|
1610
|
-
_findBelongsToByJsonApiResource(
|
|
1607
|
+
_findBelongsToByJsonApiResource(
|
|
1608
|
+
resource,
|
|
1609
|
+
parentInternalModel: InternalModel,
|
|
1610
|
+
relationshipMeta,
|
|
1611
|
+
options
|
|
1612
|
+
): Promise<InternalModel | null> {
|
|
1611
1613
|
if (!resource) {
|
|
1612
1614
|
return resolve(null);
|
|
1613
1615
|
}
|
|
@@ -1626,7 +1628,7 @@ abstract class CoreStore extends Service {
|
|
|
1626
1628
|
// short circuit if we are already loading
|
|
1627
1629
|
let pendingRequest = this._fetchManager.getPendingFetch(internalModel.identifier, options);
|
|
1628
1630
|
if (pendingRequest) {
|
|
1629
|
-
return pendingRequest.then(() => internalModel
|
|
1631
|
+
return pendingRequest.then(() => internalModel);
|
|
1630
1632
|
}
|
|
1631
1633
|
}
|
|
1632
1634
|
|
|
@@ -1659,14 +1661,12 @@ abstract class CoreStore extends Service {
|
|
|
1659
1661
|
let resourceIsLocal = !localDataIsEmpty && resource.data.id === null;
|
|
1660
1662
|
|
|
1661
1663
|
if (internalModel && resourceIsLocal) {
|
|
1662
|
-
return resolve(internalModel
|
|
1664
|
+
return resolve(internalModel);
|
|
1663
1665
|
}
|
|
1664
1666
|
|
|
1665
1667
|
// fetch by data
|
|
1666
1668
|
if (internalModel && !localDataIsEmpty) {
|
|
1667
|
-
return this._scheduleFetch(internalModel, options)
|
|
1668
|
-
return internalModel.getRecord();
|
|
1669
|
-
});
|
|
1669
|
+
return this._scheduleFetch(internalModel, options);
|
|
1670
1670
|
}
|
|
1671
1671
|
|
|
1672
1672
|
// we were explicitly told we have no data and no links.
|
|
@@ -1725,7 +1725,7 @@ abstract class CoreStore extends Service {
|
|
|
1725
1725
|
@param {Object} options optional, may include `adapterOptions` hash which will be passed to adapter.query
|
|
1726
1726
|
@return {Promise} promise
|
|
1727
1727
|
*/
|
|
1728
|
-
query(modelName: string, query, options): PromiseArray<
|
|
1728
|
+
query(modelName: string, query, options): PromiseArray<RecordInstance, AdapterPopulatedRecordArray> {
|
|
1729
1729
|
if (DEBUG) {
|
|
1730
1730
|
assertDestroyingStore(this, 'query');
|
|
1731
1731
|
}
|
|
@@ -1743,10 +1743,10 @@ abstract class CoreStore extends Service {
|
|
|
1743
1743
|
}
|
|
1744
1744
|
|
|
1745
1745
|
let normalizedModelName = normalizeModelName(modelName);
|
|
1746
|
-
return this._query(normalizedModelName, query, null, adapterOptionsWrapper);
|
|
1746
|
+
return promiseArray(this._query(normalizedModelName, query, null, adapterOptionsWrapper));
|
|
1747
1747
|
}
|
|
1748
1748
|
|
|
1749
|
-
_query(modelName: string, query, array, options):
|
|
1749
|
+
_query(modelName: string, query, array, options): Promise<AdapterPopulatedRecordArray> {
|
|
1750
1750
|
assert(`You need to pass a model name to the store's query method`, isPresent(modelName));
|
|
1751
1751
|
assert(`You need to pass a query hash to the store's query method`, query);
|
|
1752
1752
|
assert(
|
|
@@ -1762,7 +1762,7 @@ abstract class CoreStore extends Service {
|
|
|
1762
1762
|
typeof adapter.query === 'function'
|
|
1763
1763
|
);
|
|
1764
1764
|
|
|
1765
|
-
return
|
|
1765
|
+
return _query(adapter, this, modelName, query, array, options) as unknown as Promise<AdapterPopulatedRecordArray>;
|
|
1766
1766
|
}
|
|
1767
1767
|
|
|
1768
1768
|
/**
|
|
@@ -1863,7 +1863,7 @@ abstract class CoreStore extends Service {
|
|
|
1863
1863
|
@param {Object} options optional, may include `adapterOptions` hash which will be passed to adapter.queryRecord
|
|
1864
1864
|
@return {Promise} promise which resolves with the found record or `null`
|
|
1865
1865
|
*/
|
|
1866
|
-
queryRecord(modelName, query, options) {
|
|
1866
|
+
queryRecord(modelName: string, query, options): PromiseObject<RecordInstance | null> {
|
|
1867
1867
|
if (DEBUG) {
|
|
1868
1868
|
assertDestroyingStore(this, 'queryRecord');
|
|
1869
1869
|
}
|
|
@@ -1888,15 +1888,17 @@ abstract class CoreStore extends Service {
|
|
|
1888
1888
|
typeof adapter.queryRecord === 'function'
|
|
1889
1889
|
);
|
|
1890
1890
|
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1891
|
+
const promise: Promise<InternalModel | null> = _queryRecord(
|
|
1892
|
+
adapter,
|
|
1893
|
+
this,
|
|
1894
|
+
normalizedModelName,
|
|
1895
|
+
query,
|
|
1896
|
+
adapterOptionsWrapper
|
|
1897
|
+
) as Promise<InternalModel | null>;
|
|
1898
1898
|
|
|
1899
|
-
|
|
1899
|
+
return promiseObject(
|
|
1900
|
+
promise.then((internalModel: InternalModel | null) => {
|
|
1901
|
+
return internalModel ? internalModel.getRecord() : null;
|
|
1900
1902
|
})
|
|
1901
1903
|
);
|
|
1902
1904
|
}
|
|
@@ -2089,7 +2091,10 @@ abstract class CoreStore extends Service {
|
|
|
2089
2091
|
@param {Object} options
|
|
2090
2092
|
@return {Promise} promise
|
|
2091
2093
|
*/
|
|
2092
|
-
findAll(
|
|
2094
|
+
findAll(
|
|
2095
|
+
modelName: string,
|
|
2096
|
+
options: { reload?: boolean; backgroundReload?: boolean } = {}
|
|
2097
|
+
): PromiseArray<RecordInstance, RecordArray> {
|
|
2093
2098
|
if (DEBUG) {
|
|
2094
2099
|
assertDestroyingStore(this, 'findAll');
|
|
2095
2100
|
}
|
|
@@ -2102,7 +2107,7 @@ abstract class CoreStore extends Service {
|
|
|
2102
2107
|
let normalizedModelName = normalizeModelName(modelName);
|
|
2103
2108
|
let fetch = this._fetchAll(normalizedModelName, this.peekAll(normalizedModelName), options);
|
|
2104
2109
|
|
|
2105
|
-
return fetch;
|
|
2110
|
+
return promiseArray(fetch);
|
|
2106
2111
|
}
|
|
2107
2112
|
|
|
2108
2113
|
/**
|
|
@@ -2112,7 +2117,11 @@ abstract class CoreStore extends Service {
|
|
|
2112
2117
|
@param {RecordArray} array
|
|
2113
2118
|
@return {Promise} promise
|
|
2114
2119
|
*/
|
|
2115
|
-
_fetchAll(
|
|
2120
|
+
_fetchAll(
|
|
2121
|
+
modelName: string,
|
|
2122
|
+
array: RecordArray,
|
|
2123
|
+
options: { reload?: boolean; backgroundReload?: boolean }
|
|
2124
|
+
): Promise<RecordArray> {
|
|
2116
2125
|
let adapter = this.adapterFor(modelName);
|
|
2117
2126
|
|
|
2118
2127
|
assert(`You tried to load all records but you have no adapter (for ${modelName})`, adapter);
|
|
@@ -2123,7 +2132,7 @@ abstract class CoreStore extends Service {
|
|
|
2123
2132
|
|
|
2124
2133
|
if (options.reload) {
|
|
2125
2134
|
set(array, 'isUpdating', true);
|
|
2126
|
-
return
|
|
2135
|
+
return _findAll(adapter, this, modelName, options);
|
|
2127
2136
|
}
|
|
2128
2137
|
|
|
2129
2138
|
let snapshotArray = array._createSnapshot(options);
|
|
@@ -2134,12 +2143,12 @@ abstract class CoreStore extends Service {
|
|
|
2134
2143
|
(!adapter.shouldReloadAll && snapshotArray.length === 0)
|
|
2135
2144
|
) {
|
|
2136
2145
|
set(array, 'isUpdating', true);
|
|
2137
|
-
return
|
|
2146
|
+
return _findAll(adapter, this, modelName, options);
|
|
2138
2147
|
}
|
|
2139
2148
|
}
|
|
2140
2149
|
|
|
2141
2150
|
if (options.backgroundReload === false) {
|
|
2142
|
-
return
|
|
2151
|
+
return resolve(array);
|
|
2143
2152
|
}
|
|
2144
2153
|
|
|
2145
2154
|
if (
|
|
@@ -2151,7 +2160,7 @@ abstract class CoreStore extends Service {
|
|
|
2151
2160
|
_findAll(adapter, this, modelName, options);
|
|
2152
2161
|
}
|
|
2153
2162
|
|
|
2154
|
-
return
|
|
2163
|
+
return resolve(array);
|
|
2155
2164
|
}
|
|
2156
2165
|
|
|
2157
2166
|
/**
|
|
@@ -2159,7 +2168,7 @@ abstract class CoreStore extends Service {
|
|
|
2159
2168
|
@param {String} modelName
|
|
2160
2169
|
@private
|
|
2161
2170
|
*/
|
|
2162
|
-
_didUpdateAll(modelName) {
|
|
2171
|
+
_didUpdateAll(modelName: string): void {
|
|
2163
2172
|
this.recordArrayManager._didUpdateAll(modelName);
|
|
2164
2173
|
}
|
|
2165
2174
|
|
|
@@ -2258,7 +2267,11 @@ abstract class CoreStore extends Service {
|
|
|
2258
2267
|
@param {Resolver} resolver
|
|
2259
2268
|
@param {Object} options
|
|
2260
2269
|
*/
|
|
2261
|
-
scheduleSave(
|
|
2270
|
+
scheduleSave(
|
|
2271
|
+
internalModel: InternalModel,
|
|
2272
|
+
resolver: RSVP.Deferred<void>,
|
|
2273
|
+
options: FindOptions
|
|
2274
|
+
): void | Promise<void> {
|
|
2262
2275
|
if (internalModel._isRecordFullyDeleted()) {
|
|
2263
2276
|
resolver.resolve();
|
|
2264
2277
|
return resolver.promise;
|
|
@@ -2279,9 +2292,8 @@ abstract class CoreStore extends Service {
|
|
|
2279
2292
|
operation = 'deleteRecord';
|
|
2280
2293
|
}
|
|
2281
2294
|
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
let fetchManagerPromise = this._fetchManager.scheduleSave(internalModel.identifier, options);
|
|
2295
|
+
const saveOptions = Object.assign({ [SaveOp]: operation }, options);
|
|
2296
|
+
let fetchManagerPromise = this._fetchManager.scheduleSave(internalModel.identifier, saveOptions);
|
|
2285
2297
|
let promise = fetchManagerPromise.then(
|
|
2286
2298
|
(payload) => {
|
|
2287
2299
|
/*
|
|
@@ -2822,10 +2834,6 @@ abstract class CoreStore extends Service {
|
|
|
2822
2834
|
serializer.pushPayload(this, payload);
|
|
2823
2835
|
}
|
|
2824
2836
|
|
|
2825
|
-
reloadManyArray(manyArray, internalModel, key, options) {
|
|
2826
|
-
return internalModel.reloadHasMany(key, options);
|
|
2827
|
-
}
|
|
2828
|
-
|
|
2829
2837
|
reloadBelongsTo(belongsToProxy, internalModel, key, options) {
|
|
2830
2838
|
return internalModel.reloadBelongsTo(key, options);
|
|
2831
2839
|
}
|
|
@@ -2852,13 +2860,13 @@ abstract class CoreStore extends Service {
|
|
|
2852
2860
|
return internalModel!.createSnapshot(options).serialize(options);
|
|
2853
2861
|
}
|
|
2854
2862
|
|
|
2855
|
-
saveRecord(record: RecordInstance, options?: Dict<unknown>):
|
|
2863
|
+
saveRecord(record: RecordInstance, options?: Dict<unknown>): Promise<RecordInstance> {
|
|
2856
2864
|
let identifier = recordIdentifierFor(record);
|
|
2857
2865
|
let internalModel = internalModelFactoryFor(this).peek(identifier);
|
|
2858
2866
|
// TODO we used to check if the record was destroyed here
|
|
2859
2867
|
// Casting can be removed once REQUEST_SERVICE ff is turned on
|
|
2860
2868
|
// because a `Record` is provided there will always be a matching internalModel
|
|
2861
|
-
return (internalModel!.save(options) as
|
|
2869
|
+
return (internalModel!.save(options) as Promise<void>).then(() => record);
|
|
2862
2870
|
}
|
|
2863
2871
|
|
|
2864
2872
|
relationshipReferenceFor(identifier: RecordIdentifier, key: string): BelongsToReference | HasManyReference {
|
|
@@ -2908,7 +2916,9 @@ abstract class CoreStore extends Service {
|
|
|
2908
2916
|
// it can be reproduced in partner tests by running
|
|
2909
2917
|
// node ./scripts/packages-for-commit.js && yarn test-external:ember-observer
|
|
2910
2918
|
if (_RecordData === undefined) {
|
|
2911
|
-
_RecordData =
|
|
2919
|
+
_RecordData = (
|
|
2920
|
+
importSync('@ember-data/record-data/-private') as typeof import('@ember-data/record-data/-private')
|
|
2921
|
+
).RecordData as RecordDataConstruct;
|
|
2912
2922
|
}
|
|
2913
2923
|
|
|
2914
2924
|
let identifier = this.identifierCache.getOrCreateRecordIdentifier({
|
|
@@ -2966,7 +2976,7 @@ abstract class CoreStore extends Service {
|
|
|
2966
2976
|
@param {Object} payload
|
|
2967
2977
|
@return {Object} The normalized payload
|
|
2968
2978
|
*/
|
|
2969
|
-
normalize(modelName, payload) {
|
|
2979
|
+
normalize(modelName: string, payload) {
|
|
2970
2980
|
if (DEBUG) {
|
|
2971
2981
|
assertDestroyingStore(this, 'normalize');
|
|
2972
2982
|
}
|
|
@@ -2982,7 +2992,7 @@ abstract class CoreStore extends Service {
|
|
|
2982
2992
|
let model = this.modelFor(normalizedModelName);
|
|
2983
2993
|
assert(
|
|
2984
2994
|
`You must define a normalize method in your serializer in order to call store.normalize`,
|
|
2985
|
-
serializer
|
|
2995
|
+
serializer?.normalize
|
|
2986
2996
|
);
|
|
2987
2997
|
return serializer.normalize(model, payload);
|
|
2988
2998
|
}
|
|
@@ -3096,7 +3106,7 @@ abstract class CoreStore extends Service {
|
|
|
3096
3106
|
@param {String} modelName the record to serialize
|
|
3097
3107
|
@return {Serializer}
|
|
3098
3108
|
*/
|
|
3099
|
-
serializerFor(modelName) {
|
|
3109
|
+
serializerFor(modelName: string): MinimumSerializerInterface | null {
|
|
3100
3110
|
if (DEBUG) {
|
|
3101
3111
|
assertDestroyingStore(this, 'serializerFor');
|
|
3102
3112
|
}
|
|
@@ -3132,30 +3142,29 @@ abstract class CoreStore extends Service {
|
|
|
3132
3142
|
return serializer;
|
|
3133
3143
|
}
|
|
3134
3144
|
|
|
3135
|
-
|
|
3136
|
-
`No serializer was found for '${modelName}' and no 'application' serializer was found as a fallback`,
|
|
3137
|
-
serializer !== undefined
|
|
3138
|
-
);
|
|
3145
|
+
return null;
|
|
3139
3146
|
}
|
|
3140
3147
|
|
|
3141
3148
|
destroy() {
|
|
3142
3149
|
// enqueue destruction of any adapters/serializers we have created
|
|
3143
3150
|
for (let adapterName in this._adapterCache) {
|
|
3144
|
-
let adapter = this._adapterCache[adapterName]
|
|
3151
|
+
let adapter = this._adapterCache[adapterName]!;
|
|
3145
3152
|
if (typeof adapter.destroy === 'function') {
|
|
3146
3153
|
adapter.destroy();
|
|
3147
3154
|
}
|
|
3148
3155
|
}
|
|
3149
3156
|
|
|
3150
3157
|
for (let serializerName in this._serializerCache) {
|
|
3151
|
-
let serializer = this._serializerCache[serializerName]
|
|
3158
|
+
let serializer = this._serializerCache[serializerName]!;
|
|
3152
3159
|
if (typeof serializer.destroy === 'function') {
|
|
3153
3160
|
serializer.destroy();
|
|
3154
3161
|
}
|
|
3155
3162
|
}
|
|
3156
3163
|
|
|
3157
3164
|
if (HAS_RECORD_DATA_PACKAGE) {
|
|
3158
|
-
const peekGraph =
|
|
3165
|
+
const peekGraph = (
|
|
3166
|
+
importSync('@ember-data/record-data/-private') as typeof import('@ember-data/record-data/-private')
|
|
3167
|
+
).peekGraph;
|
|
3159
3168
|
let graph = peekGraph(this);
|
|
3160
3169
|
if (graph) {
|
|
3161
3170
|
graph.destroy();
|
|
@@ -3175,7 +3184,9 @@ abstract class CoreStore extends Service {
|
|
|
3175
3184
|
// since then we avoid churning relationships
|
|
3176
3185
|
// during unload
|
|
3177
3186
|
if (HAS_RECORD_DATA_PACKAGE) {
|
|
3178
|
-
const peekGraph =
|
|
3187
|
+
const peekGraph = (
|
|
3188
|
+
importSync('@ember-data/record-data/-private') as typeof import('@ember-data/record-data/-private')
|
|
3189
|
+
).peekGraph;
|
|
3179
3190
|
let graph = peekGraph(this);
|
|
3180
3191
|
if (graph) {
|
|
3181
3192
|
graph.willDestroy();
|