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