@ember-data/store 4.4.0-beta.1 → 4.5.0-beta.0

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