@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.
Files changed (32) hide show
  1. package/addon/-private/system/core-store.ts +130 -119
  2. package/addon/-private/system/ds-model-store.ts +1 -10
  3. package/addon/-private/system/fetch-manager.ts +48 -21
  4. package/addon/-private/system/model/internal-model.ts +264 -160
  5. package/addon/-private/system/{promise-proxies.js → promise-proxies.ts} +31 -21
  6. package/addon/-private/system/promise-proxy-base.js +7 -0
  7. package/addon/-private/system/{record-array-manager.js → record-array-manager.ts} +87 -60
  8. package/addon/-private/system/record-arrays/adapter-populated-record-array.ts +129 -0
  9. package/addon/-private/system/record-arrays/{record-array.js → record-array.ts} +96 -75
  10. package/addon/-private/system/record-data-for.ts +2 -0
  11. package/addon/-private/system/references/belongs-to.ts +3 -2
  12. package/addon/-private/system/references/has-many.ts +4 -2
  13. package/addon/-private/system/schema-definition-service.ts +2 -2
  14. package/addon/-private/system/snapshot-record-array.ts +12 -11
  15. package/addon/-private/system/snapshot.ts +24 -7
  16. package/addon/-private/system/store/common.js +24 -1
  17. package/addon/-private/system/store/finders.js +53 -5
  18. package/addon/-private/system/store/internal-model-factory.ts +8 -7
  19. package/addon/-private/system/store/record-data-store-wrapper.ts +7 -2
  20. package/addon/-private/system/store/serializer-response.ts +85 -0
  21. package/addon/-private/ts-interfaces/ds-model.ts +15 -7
  22. package/addon/-private/ts-interfaces/ember-data-json-api.ts +3 -0
  23. package/addon/-private/ts-interfaces/minimum-adapter-interface.ts +19 -20
  24. package/addon/-private/ts-interfaces/minimum-serializer-interface.ts +27 -6
  25. package/addon/-private/ts-interfaces/record-data.ts +4 -1
  26. package/addon/-private/ts-interfaces/record-instance.ts +3 -1
  27. package/addon/-private/ts-interfaces/store.ts +1 -0
  28. package/addon/-private/utils/promise-record.ts +3 -3
  29. package/index.js +3 -0
  30. package/package.json +6 -5
  31. package/addon/-private/system/record-arrays/adapter-populated-record-array.js +0 -95
  32. 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 require from 'require';
17
- import { all, default as RSVP, Promise, resolve } from '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 type { PromiseProxy } from '../ts-interfaces/promise-proxies';
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
- public _backburner: Backburner = edBackburner;
180
- public recordArrayManager: RecordArrayManager = new RecordArrayManager({ store: this });
181
+ declare _backburner: Backburner;
182
+ declare recordArrayManager: RecordArrayManager;
181
183
 
182
184
  declare _notificationManager: NotificationManager;
183
185
  declare identifierCache: IdentifierCache;
184
- private _adapterCache = Object.create(null);
185
- private _serializerCache = Object.create(null);
186
- public _storeWrapper = new RecordDataStoreWrapper(this);
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
- private _updatedInternalModels: InternalModel[] = [];
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 = false;
204
- generateStackTracesForTrackedRequests: boolean = false;
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): PromiseProxy<DSModel>;
1043
- findRecord(resource: ResourceIdentifierObject, id?: FindOptions): PromiseProxy<DSModel>;
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
- ): PromiseProxy<DSModel> {
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 this._findByInternalModel(internalModel, options);
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 Promise.resolve(internalModel);
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 Promise.resolve(internalModel);
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
- let fetchedInternalModel = this._findEmptyInternalModel(internalModel, options);
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(() => Promise.resolve(internalModel));
1135
+ return pendingRequest.then(() => resolve(internalModel));
1140
1136
  }
1141
1137
  return this._scheduleFetch(internalModel, options);
1142
1138
  }
1143
1139
 
1144
- return Promise.resolve(internalModel);
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 Promise.all(fetches);
1181
+ return all(fetches);
1186
1182
  }
1187
1183
 
1188
- _scheduleFetch(internalModel: InternalModel, options = {}): RSVP.Promise<InternalModel> {
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): RSVP.Promise<InternalModel> {
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' || typeof adapter.find === '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 Promise.all(finds);
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 | BelongsToRelationship,
1518
- options: any
1519
- ): RSVP.Promise<unknown> {
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(resource, parentInternalModel, relationshipMeta, options) {
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).then(
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(resource, parentInternalModel, relationshipMeta, options) {
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.getRecord());
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.getRecord());
1664
+ return resolve(internalModel);
1663
1665
  }
1664
1666
 
1665
1667
  // fetch by data
1666
1668
  if (internalModel && !localDataIsEmpty) {
1667
- return this._scheduleFetch(internalModel, options).then(() => {
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<DSModel> {
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): PromiseArray<DSModel> {
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 promiseArray(_query(adapter, this, modelName, query, array, options));
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
- return promiseObject(
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
- }
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
- return null;
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(modelName, options) {
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(modelName, array, options: { reload?: boolean; backgroundReload?: boolean } = {}) {
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 promiseArray(_findAll(adapter, this, modelName, options));
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 promiseArray(_findAll(adapter, this, modelName, options));
2146
+ return _findAll(adapter, this, modelName, options);
2138
2147
  }
2139
2148
  }
2140
2149
 
2141
2150
  if (options.backgroundReload === false) {
2142
- return promiseArray(Promise.resolve(array));
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 promiseArray(Promise.resolve(array));
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(internalModel: InternalModel, resolver: RSVP.Deferred<void>, options): void | RSVP.Promise<void> {
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
- options[SaveOp] = operation;
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>): RSVP.Promise<RecordInstance> {
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 RSVP.Promise<void>).then(() => record);
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 = require('@ember-data/record-data/-private').RecordData as RecordDataConstruct;
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.normalize
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
- assert(
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 = require('@ember-data/record-data/-private').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 = require('@ember-data/record-data/-private').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();