@ember-data/store 4.1.0-alpha.9 → 4.2.0-alpha.2

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.
@@ -4,8 +4,7 @@
4
4
  import { getOwner } from '@ember/application';
5
5
  import { A } from '@ember/array';
6
6
  import { assert, deprecate, inspect, warn } from '@ember/debug';
7
- import { computed, defineProperty, get, set } from '@ember/object';
8
- import { assign } from '@ember/polyfills';
7
+ import { computed, defineProperty, set } from '@ember/object';
9
8
  import { _backburner as emberBackburner } from '@ember/runloop';
10
9
  import type { Backburner } from '@ember/runloop/-private/backburner';
11
10
  import Service from '@ember/service';
@@ -15,14 +14,8 @@ import { DEBUG } from '@glimmer/env';
15
14
  import Ember from 'ember';
16
15
 
17
16
  import require from 'require';
18
- import { all, default as RSVP, defer, Promise, resolve } from 'rsvp';
17
+ import { all, default as RSVP, Promise, resolve } from 'rsvp';
19
18
 
20
- import {
21
- CUSTOM_MODEL_CLASS,
22
- RECORD_DATA_ERRORS,
23
- RECORD_DATA_STATE,
24
- REQUEST_SERVICE,
25
- } from '@ember-data/canary-features';
26
19
  import {
27
20
  HAS_ADAPTER_PACKAGE,
28
21
  HAS_EMBER_DATA_PACKAGE,
@@ -31,7 +24,6 @@ import {
31
24
  } from '@ember-data/private-build-infra';
32
25
  import {
33
26
  DEPRECATE_DEFAULT_ADAPTER,
34
- DEPRECATE_DEFAULT_SERIALIZER,
35
27
  DEPRECATE_LEGACY_TEST_REGISTRATIONS,
36
28
  } from '@ember-data/private-build-infra/deprecations';
37
29
  import type {
@@ -68,10 +60,8 @@ import type { FindOptions } from '../ts-interfaces/store';
68
60
  import type { Dict } from '../ts-interfaces/utils';
69
61
  import constructResource from '../utils/construct-resource';
70
62
  import promiseRecord from '../utils/promise-record';
71
- import { addSymbol } from '../utils/symbol';
72
63
  import edBackburner from './backburner';
73
64
  import coerceId, { ensureStringId } from './coerce-id';
74
- import { errorsArrayToHash } from './errors-utils';
75
65
  import FetchManager, { SaveOp } from './fetch-manager';
76
66
  import type InternalModel from './model/internal-model';
77
67
  import {
@@ -89,8 +79,7 @@ import NotificationManager from './record-notification-manager';
89
79
  import type { BelongsToReference, HasManyReference } from './references';
90
80
  import { RecordReference } from './references';
91
81
  import type RequestCache from './request-cache';
92
- import type { default as Snapshot, PrivateSnapshot } from './snapshot';
93
- import { _bind, _guard, _objectIsAlive, guardDestroyedStore } from './store/common';
82
+ import type { default as Snapshot } from './snapshot';
94
83
  import { _find, _findAll, _findBelongsTo, _findHasMany, _findMany, _query, _queryRecord } from './store/finders';
95
84
  import {
96
85
  internalModelFactoryFor,
@@ -99,7 +88,6 @@ import {
99
88
  setRecordIdentifier,
100
89
  } from './store/internal-model-factory';
101
90
  import RecordDataStoreWrapper from './store/record-data-store-wrapper';
102
- import { normalizeResponseHelper } from './store/serializer-response';
103
91
 
104
92
  type RecordDataConstruct = typeof RecordDataClass;
105
93
  let _RecordData: RecordDataConstruct | undefined;
@@ -313,13 +301,9 @@ abstract class CoreStore extends Service {
313
301
  constructor() {
314
302
  super(...arguments);
315
303
 
316
- if (REQUEST_SERVICE) {
317
- this._fetchManager = new FetchManager(this);
318
- }
319
- if (CUSTOM_MODEL_CLASS) {
320
- this._notificationManager = new NotificationManager(this);
321
- this.__recordDataFor = this.__recordDataFor.bind(this);
322
- }
304
+ this._fetchManager = new FetchManager(this);
305
+ this._notificationManager = new NotificationManager(this);
306
+ this.__recordDataFor = this.__recordDataFor.bind(this);
323
307
 
324
308
  if (DEBUG) {
325
309
  if (HAS_EMBER_DATA_PACKAGE && HAS_SERIALIZER_PACKAGE) {
@@ -424,10 +408,7 @@ abstract class CoreStore extends Service {
424
408
  }
425
409
 
426
410
  getRequestStateService(): RequestCache {
427
- if (REQUEST_SERVICE) {
428
- return this._fetchManager.requestCache;
429
- }
430
- assert('RequestService is not available unless the feature flag is on and running on a canary build', false);
411
+ return this._fetchManager.requestCache;
431
412
  }
432
413
 
433
414
  /**
@@ -451,55 +432,51 @@ abstract class CoreStore extends Service {
451
432
  identifier: StableRecordIdentifier,
452
433
  properties?: { [key: string]: any }
453
434
  ) {
454
- if (CUSTOM_MODEL_CLASS) {
455
- // assert here
456
- if (properties !== undefined) {
457
- assert(
458
- `You passed '${properties}' as properties for record creation instead of an object.`,
459
- typeof properties === 'object' && properties !== null
460
- );
435
+ // assert here
436
+ if (properties !== undefined) {
437
+ assert(
438
+ `You passed '${properties}' as properties for record creation instead of an object.`,
439
+ typeof properties === 'object' && properties !== null
440
+ );
461
441
 
462
- if ('id' in properties) {
463
- internalModel.setId(properties.id);
464
- }
442
+ if ('id' in properties) {
443
+ internalModel.setId(properties.id);
444
+ }
465
445
 
466
- // convert relationship Records to RecordDatas before passing to RecordData
467
- let defs = this._relationshipsDefinitionFor(modelName);
468
-
469
- if (defs !== null) {
470
- let keys = Object.keys(properties);
471
- let relationshipValue;
472
-
473
- for (let i = 0; i < keys.length; i++) {
474
- let prop = keys[i];
475
- let def = defs[prop];
476
-
477
- if (def !== undefined) {
478
- if (def.kind === 'hasMany') {
479
- if (DEBUG) {
480
- assertRecordsPassedToHasMany(properties[prop]);
481
- }
482
- relationshipValue = extractRecordDatasFromRecords(properties[prop]);
483
- } else {
484
- relationshipValue = extractRecordDataFromRecord(properties[prop]);
485
- }
446
+ // convert relationship Records to RecordDatas before passing to RecordData
447
+ let defs = this._relationshipsDefinitionFor(modelName);
448
+
449
+ if (defs !== null) {
450
+ let keys = Object.keys(properties);
451
+ let relationshipValue;
452
+
453
+ for (let i = 0; i < keys.length; i++) {
454
+ let prop = keys[i];
455
+ let def = defs[prop];
486
456
 
487
- properties[prop] = relationshipValue;
457
+ if (def !== undefined) {
458
+ if (def.kind === 'hasMany') {
459
+ if (DEBUG) {
460
+ assertRecordsPassedToHasMany(properties[prop]);
461
+ }
462
+ relationshipValue = extractRecordDatasFromRecords(properties[prop]);
463
+ } else {
464
+ relationshipValue = extractRecordDataFromRecord(properties[prop]);
488
465
  }
466
+
467
+ properties[prop] = relationshipValue;
489
468
  }
490
469
  }
491
470
  }
492
-
493
- // TODO guard against initRecordOptions no being there
494
- let createOptions = recordData._initRecordCreateOptions(properties);
495
- //TODO Igor pass a wrapper instead of RD
496
- let record = this.instantiateRecord(identifier, createOptions, this.__recordDataFor, this._notificationManager);
497
- setRecordIdentifier(record, identifier);
498
- //recordToInternalModelMap.set(record, internalModel);
499
- return record;
500
471
  }
501
472
 
502
- assert('should not be here, custom model class ff error', false);
473
+ // TODO guard against initRecordOptions no being there
474
+ let createOptions = recordData._initRecordCreateOptions(properties);
475
+ //TODO Igor pass a wrapper instead of RD
476
+ let record = this.instantiateRecord(identifier, createOptions, this.__recordDataFor, this._notificationManager);
477
+ setRecordIdentifier(record, identifier);
478
+ //recordToInternalModelMap.set(record, internalModel);
479
+ return record;
503
480
  }
504
481
 
505
482
  abstract instantiateRecord(
@@ -537,10 +514,7 @@ abstract class CoreStore extends Service {
537
514
  }
538
515
 
539
516
  getSchemaDefinitionService(): SchemaDefinitionService {
540
- if (CUSTOM_MODEL_CLASS) {
541
- return this._schemaDefinitionService;
542
- }
543
- assert('need to enable CUSTOM_MODEL_CLASS feature flag in order to access SchemaDefinitionService');
517
+ return this._schemaDefinitionService;
544
518
  }
545
519
 
546
520
  // TODO Double check this return value is correct
@@ -646,7 +620,7 @@ abstract class CoreStore extends Service {
646
620
  return emberBackburner.join(() => {
647
621
  return this._backburner.join(() => {
648
622
  let normalizedModelName = normalizeModelName(modelName);
649
- let properties = assign({}, inputProperties);
623
+ let properties = { ...inputProperties };
650
624
 
651
625
  // If the passed properties do not include a primary key,
652
626
  // give the adapter an opportunity to generate one. Typically,
@@ -718,31 +692,12 @@ abstract class CoreStore extends Service {
718
692
  assertDestroyingStore(this, 'deleteRecord');
719
693
  }
720
694
  this._backburner.join(() => {
721
- if (CUSTOM_MODEL_CLASS) {
722
- let identifier = peekRecordIdentifier(record);
723
- if (identifier) {
724
- let internalModel = internalModelFactoryFor(this).peek(identifier);
725
- if (internalModel) {
726
- internalModel.deleteRecord();
727
- }
728
- } else {
729
- deprecate(
730
- `You passed a non ember-data managed record ${record} to store.deleteRecord. Ember Data store is not meant to manage non store records. This is not supported and will be removed`,
731
- false,
732
- {
733
- id: 'ember-data:delete-record-non-store',
734
- until: '4.0',
735
- for: '@ember-data/store',
736
- since: {
737
- available: '3.28',
738
- enabled: '3.28',
739
- },
740
- }
741
- );
742
- record.deleteRecord();
695
+ let identifier = peekRecordIdentifier(record);
696
+ if (identifier) {
697
+ let internalModel = internalModelFactoryFor(this).peek(identifier);
698
+ if (internalModel) {
699
+ internalModel.deleteRecord();
743
700
  }
744
- } else {
745
- record.deleteRecord();
746
701
  }
747
702
  });
748
703
  }
@@ -767,31 +722,12 @@ abstract class CoreStore extends Service {
767
722
  if (DEBUG) {
768
723
  assertDestroyingStore(this, 'unloadRecord');
769
724
  }
770
- if (CUSTOM_MODEL_CLASS) {
771
- let identifier = peekRecordIdentifier(record);
772
- if (identifier) {
773
- let internalModel = internalModelFactoryFor(this).peek(identifier);
774
- if (internalModel) {
775
- internalModel.unloadRecord();
776
- }
777
- } else {
778
- deprecate(
779
- `You passed a non ember-data managed record ${record} to store.unloadRecord. Ember Data store is not meant to manage non store records. This is not supported and will be removed`,
780
- false,
781
- {
782
- id: 'ember-data:unload-record-non-store',
783
- until: '4.0',
784
- for: '@ember-data/store',
785
- since: {
786
- available: '3.28',
787
- enabled: '3.28',
788
- },
789
- }
790
- );
791
- record.unloadRecord();
725
+ let identifier = peekRecordIdentifier(record);
726
+ if (identifier) {
727
+ let internalModel = internalModelFactoryFor(this).peek(identifier);
728
+ if (internalModel) {
729
+ internalModel.unloadRecord();
792
730
  }
793
- } else {
794
- record.unloadRecord();
795
731
  }
796
732
  }
797
733
 
@@ -1280,7 +1216,7 @@ abstract class CoreStore extends Service {
1280
1216
  return Promise.resolve(internalModel);
1281
1217
  }
1282
1218
 
1283
- _findByInternalModel(internalModel, options: { preload?: any } = {}) {
1219
+ _findByInternalModel(internalModel: InternalModel, options: FindOptions = {}) {
1284
1220
  if (options.preload) {
1285
1221
  this._backburner.join(() => {
1286
1222
  internalModel.preloadData(options.preload);
@@ -1295,24 +1231,17 @@ abstract class CoreStore extends Service {
1295
1231
  );
1296
1232
  }
1297
1233
 
1298
- _findEmptyInternalModel(internalModel, options) {
1234
+ _findEmptyInternalModel(internalModel: InternalModel, options: FindOptions) {
1299
1235
  if (internalModel.currentState.isEmpty) {
1300
1236
  return this._scheduleFetch(internalModel, options);
1301
1237
  }
1302
1238
 
1303
- //TODO double check about reloading
1304
- if (!REQUEST_SERVICE) {
1305
- if (internalModel.currentState.isLoading) {
1306
- return internalModel._promiseProxy;
1307
- }
1308
- } else {
1309
- if (internalModel.currentState.isLoading) {
1310
- let pending = this._fetchManager.getPendingFetch(internalModel.identifier);
1311
- if (pending) {
1312
- return pending.then(() => Promise.resolve(internalModel));
1313
- }
1314
- return this._scheduleFetch(internalModel, options);
1239
+ if (internalModel.currentState.isLoading) {
1240
+ let pendingRequest = this._fetchManager.getPendingFetch(internalModel.identifier, options);
1241
+ if (pendingRequest) {
1242
+ return pendingRequest.then(() => Promise.resolve(internalModel));
1315
1243
  }
1244
+ return this._scheduleFetch(internalModel, options);
1316
1245
  }
1317
1246
 
1318
1247
  return Promise.resolve(internalModel);
@@ -1418,74 +1347,12 @@ abstract class CoreStore extends Service {
1418
1347
  }
1419
1348
 
1420
1349
  _scheduleFetch(internalModel: InternalModel, options): RSVP.Promise<InternalModel> {
1421
- if (REQUEST_SERVICE) {
1422
- return this._scheduleFetchThroughFetchManager(internalModel, options);
1423
- } else {
1424
- if (internalModel._promiseProxy) {
1425
- return internalModel._promiseProxy;
1426
- }
1427
-
1428
- assertIdentifierHasId(internalModel.identifier);
1429
-
1430
- let { id, modelName } = internalModel;
1431
- let resolver = defer<InternalModel>(`Fetching ${modelName}' with id: ${id}`);
1432
- let pendingFetchItem: PendingFetchItem = {
1433
- internalModel,
1434
- resolver,
1435
- options,
1436
- };
1437
-
1438
- if (DEBUG) {
1439
- if (this.generateStackTracesForTrackedRequests === true) {
1440
- let trace;
1441
-
1442
- try {
1443
- throw new Error(`Trace Origin for scheduled fetch for ${modelName}:${id}.`);
1444
- } catch (e) {
1445
- trace = e;
1446
- }
1447
-
1448
- // enable folks to discover the origin of this findRecord call when
1449
- // debugging. Ideally we would have a tracked queue for requests with
1450
- // labels or local IDs that could be used to merge this trace with
1451
- // the trace made available when we detect an async leak
1452
- pendingFetchItem.trace = trace;
1453
- }
1454
- }
1455
-
1456
- let promise = resolver.promise;
1457
-
1458
- internalModel.send('loadingData', promise);
1459
- if (this._pendingFetch.size === 0) {
1460
- emberBackburner.schedule('actions', this, this.flushAllPendingFetches);
1461
- }
1462
-
1463
- let fetches = this._pendingFetch;
1464
- let pending = fetches.get(modelName);
1465
-
1466
- if (pending === undefined) {
1467
- pending = [];
1468
- fetches.set(modelName, pending);
1469
- }
1470
-
1471
- pending.push(pendingFetchItem);
1472
-
1473
- return promise;
1474
- }
1350
+ return this._scheduleFetchThroughFetchManager(internalModel, options);
1475
1351
  }
1476
1352
 
1477
1353
  flushAllPendingFetches() {
1478
- if (REQUEST_SERVICE) {
1479
- return;
1480
- //assert here
1481
- } else {
1482
- if (this.isDestroyed || this.isDestroying) {
1483
- return;
1484
- }
1485
-
1486
- this._pendingFetch.forEach(this._flushPendingFetchForType, this);
1487
- this._pendingFetch.clear();
1488
- }
1354
+ return;
1355
+ //assert here
1489
1356
  }
1490
1357
 
1491
1358
  _flushPendingFetchForType(pendingFetchItems: PendingFetchItem[], modelName: string) {
@@ -1601,18 +1468,14 @@ abstract class CoreStore extends Service {
1601
1468
  groups = [snapshots];
1602
1469
  }
1603
1470
 
1604
- // we use var here because babel transpiles let
1605
- // in a manner that causes a mega-bad perf scenario here
1606
- // when targets no longer include IE11 we can drop this.
1607
- /* eslint-disable no-var */
1608
- for (var i = 0, l = groups.length; i < l; i++) {
1609
- var group = groups[i];
1610
- var totalInGroup = groups[i].length;
1611
- var ids = new Array(totalInGroup);
1612
- var groupedInternalModels = new Array(totalInGroup);
1471
+ for (let i = 0, l = groups.length; i < l; i++) {
1472
+ let group = groups[i];
1473
+ let totalInGroup = groups[i].length;
1474
+ let ids = new Array(totalInGroup);
1475
+ let groupedInternalModels = new Array(totalInGroup);
1613
1476
 
1614
- for (var j = 0; j < totalInGroup; j++) {
1615
- var internalModel = group[j]._internalModel;
1477
+ for (let j = 0; j < totalInGroup; j++) {
1478
+ let internalModel = group[j]._internalModel;
1616
1479
 
1617
1480
  groupedInternalModels[j] = internalModel;
1618
1481
  ids[j] = internalModel.id;
@@ -1629,7 +1492,7 @@ abstract class CoreStore extends Service {
1629
1492
  });
1630
1493
  })(groupedInternalModels);
1631
1494
  } else if (ids.length === 1) {
1632
- var pair = seeking[groupedInternalModels[0].id];
1495
+ let pair = seeking[groupedInternalModels[0].id];
1633
1496
  _fetchRecord(pair);
1634
1497
  } else {
1635
1498
  assert("You cannot return an empty array from adapter's method groupRecordsForFindMany");
@@ -1765,7 +1628,7 @@ abstract class CoreStore extends Service {
1765
1628
  if (arguments.length === 1 && isMaybeIdentifier(identifier)) {
1766
1629
  let stableIdentifier = identifierCacheFor(this).peekRecordIdentifier(identifier);
1767
1630
  if (stableIdentifier) {
1768
- return internalModelFactoryFor(this).peek(stableIdentifier)?.getRecord();
1631
+ return internalModelFactoryFor(this).peek(stableIdentifier)?.getRecord() || null;
1769
1632
  }
1770
1633
  return null;
1771
1634
  }
@@ -1805,9 +1668,7 @@ abstract class CoreStore extends Service {
1805
1668
  @return {Promise} promise
1806
1669
  */
1807
1670
  _reloadRecord(internalModel, options): RSVP.Promise<InternalModel> {
1808
- if (REQUEST_SERVICE) {
1809
- options.isReloading = true;
1810
- }
1671
+ options.isReloading = true;
1811
1672
  let { id, modelName } = internalModel;
1812
1673
  let adapter = this.adapterFor(modelName);
1813
1674
 
@@ -2054,17 +1915,9 @@ abstract class CoreStore extends Service {
2054
1915
 
2055
1916
  if (internalModel) {
2056
1917
  // short circuit if we are already loading
2057
- if (REQUEST_SERVICE) {
2058
- let pendingRequest = this._fetchManager.getPendingFetch(internalModel.identifier);
2059
- if (pendingRequest) {
2060
- return pendingRequest.then(() => internalModel.getRecord());
2061
- }
2062
- } else {
2063
- if (internalModel.currentState.isLoading) {
2064
- return internalModel._promiseProxy.then(() => {
2065
- return internalModel.getRecord();
2066
- });
2067
- }
1918
+ let pendingRequest = this._fetchManager.getPendingFetch(internalModel.identifier, options);
1919
+ if (pendingRequest) {
1920
+ return pendingRequest.then(() => internalModel.getRecord());
2068
1921
  }
2069
1922
  }
2070
1923
 
@@ -2087,6 +1940,10 @@ abstract class CoreStore extends Service {
2087
1940
  return resolve(null);
2088
1941
  }
2089
1942
 
1943
+ if (!internalModel) {
1944
+ assert(`No InternalModel found for ${resource.lid}`, internalModel);
1945
+ }
1946
+
2090
1947
  return this._findByInternalModel(internalModel, options);
2091
1948
  }
2092
1949
 
@@ -2693,33 +2550,32 @@ abstract class CoreStore extends Service {
2693
2550
  @param {Object} options
2694
2551
  */
2695
2552
  scheduleSave(internalModel: InternalModel, resolver: RSVP.Deferred<void>, options): void | RSVP.Promise<void> {
2696
- if (REQUEST_SERVICE) {
2697
- if (internalModel._isRecordFullyDeleted()) {
2698
- resolver.resolve();
2699
- return resolver.promise;
2700
- }
2553
+ if (internalModel._isRecordFullyDeleted()) {
2554
+ resolver.resolve();
2555
+ return resolver.promise;
2556
+ }
2701
2557
 
2702
- internalModel.adapterWillCommit();
2558
+ internalModel.adapterWillCommit();
2703
2559
 
2704
- if (!options) {
2705
- options = {};
2706
- }
2707
- let recordData = internalModel._recordData;
2708
- let operation: 'createRecord' | 'deleteRecord' | 'updateRecord' = 'updateRecord';
2709
-
2710
- // TODO handle missing isNew
2711
- if (recordData.isNew && recordData.isNew()) {
2712
- operation = 'createRecord';
2713
- } else if (recordData.isDeleted && recordData.isDeleted()) {
2714
- operation = 'deleteRecord';
2715
- }
2560
+ if (!options) {
2561
+ options = {};
2562
+ }
2563
+ let recordData = internalModel._recordData;
2564
+ let operation: 'createRecord' | 'deleteRecord' | 'updateRecord' = 'updateRecord';
2565
+
2566
+ // TODO handle missing isNew
2567
+ if (recordData.isNew && recordData.isNew()) {
2568
+ operation = 'createRecord';
2569
+ } else if (recordData.isDeleted && recordData.isDeleted()) {
2570
+ operation = 'deleteRecord';
2571
+ }
2716
2572
 
2717
- addSymbol(options, SaveOp, operation);
2573
+ options[SaveOp] = operation;
2718
2574
 
2719
- let fetchManagerPromise = this._fetchManager.scheduleSave(internalModel.identifier, options);
2720
- let promise = fetchManagerPromise.then(
2721
- (payload) => {
2722
- /*
2575
+ let fetchManagerPromise = this._fetchManager.scheduleSave(internalModel.identifier, options);
2576
+ let promise = fetchManagerPromise.then(
2577
+ (payload) => {
2578
+ /*
2723
2579
  Note to future spelunkers hoping to optimize.
2724
2580
  We rely on this `run` to create a run loop if needed
2725
2581
  that `store._push` and `store.didSaveRecord` will both share.
@@ -2728,40 +2584,25 @@ abstract class CoreStore extends Service {
2728
2584
  have an outer run loop available still from the first
2729
2585
  call to `store._push`;
2730
2586
  */
2731
- this._backburner.join(() => {
2732
- let data = payload && payload.data;
2733
- this.didSaveRecord(internalModel, { data }, operation);
2734
- if (payload && payload.included) {
2735
- this._push({ data: null, included: payload.included });
2736
- }
2737
- });
2738
- },
2739
- (e) => {
2740
- if (typeof e === 'string') {
2741
- throw e;
2587
+ this._backburner.join(() => {
2588
+ let data = payload && payload.data;
2589
+ this.didSaveRecord(internalModel, { data }, operation);
2590
+ if (payload && payload.included) {
2591
+ this._push({ data: null, included: payload.included });
2742
2592
  }
2743
- const { error, parsedErrors } = e;
2744
- this.recordWasInvalid(internalModel, parsedErrors, error);
2745
- throw error;
2593
+ });
2594
+ },
2595
+ (e) => {
2596
+ if (typeof e === 'string') {
2597
+ throw e;
2746
2598
  }
2747
- );
2748
-
2749
- return promise;
2750
- } else {
2751
- if (internalModel._isRecordFullyDeleted()) {
2752
- resolver.resolve();
2753
- return;
2599
+ const { error, parsedErrors } = e;
2600
+ this.recordWasInvalid(internalModel, parsedErrors, error);
2601
+ throw error;
2754
2602
  }
2603
+ );
2755
2604
 
2756
- let snapshot = internalModel.createSnapshot(options);
2757
- internalModel.adapterWillCommit();
2758
- this._pendingSave.push({
2759
- snapshot: snapshot,
2760
- resolver: resolver,
2761
- });
2762
-
2763
- emberBackburner.scheduleOnce('actions', this, this.flushPendingSave);
2764
- }
2605
+ return promise;
2765
2606
  }
2766
2607
 
2767
2608
  /**
@@ -2772,47 +2613,8 @@ abstract class CoreStore extends Service {
2772
2613
  @private
2773
2614
  */
2774
2615
  flushPendingSave() {
2775
- if (REQUEST_SERVICE) {
2776
- // assert here
2777
- return;
2778
- }
2779
- let pending = this._pendingSave.slice();
2780
- this._pendingSave = [];
2781
-
2782
- for (let i = 0, j = pending.length; i < j; i++) {
2783
- let pendingItem = pending[i];
2784
- let snapshot = pendingItem.snapshot;
2785
- let resolver = pendingItem.resolver;
2786
- // TODO We have to cast due to our reliance on this private property
2787
- // this will be refactored away once we change our pending API to be identifier based
2788
- let internalModel = (snapshot as unknown as PrivateSnapshot)._internalModel;
2789
- let adapter = this.adapterFor(internalModel.modelName);
2790
- let operation;
2791
-
2792
- if (RECORD_DATA_STATE) {
2793
- // TODO move this out of internalModel
2794
- if (internalModel.isNew()) {
2795
- operation = 'createRecord';
2796
- } else if (internalModel.isDeleted()) {
2797
- operation = 'deleteRecord';
2798
- } else {
2799
- operation = 'updateRecord';
2800
- }
2801
- } else {
2802
- if (internalModel.currentState.stateName === 'root.deleted.saved') {
2803
- resolver.resolve();
2804
- continue;
2805
- } else if (internalModel.isNew()) {
2806
- operation = 'createRecord';
2807
- } else if (internalModel.isDeleted()) {
2808
- operation = 'deleteRecord';
2809
- } else {
2810
- operation = 'updateRecord';
2811
- }
2812
- }
2813
-
2814
- resolver.resolve(_commit(adapter, this, operation, snapshot));
2815
- }
2616
+ // assert here
2617
+ return;
2816
2618
  }
2817
2619
 
2818
2620
  /**
@@ -2870,11 +2672,7 @@ abstract class CoreStore extends Service {
2870
2672
  if (DEBUG) {
2871
2673
  assertDestroyingStore(this, 'recordWasInvalid');
2872
2674
  }
2873
- if (RECORD_DATA_ERRORS) {
2874
- internalModel.adapterDidInvalidate(parsedErrors, error);
2875
- } else {
2876
- internalModel.adapterDidInvalidate(parsedErrors);
2877
- }
2675
+ internalModel.adapterDidInvalidate(parsedErrors, error);
2878
2676
  }
2879
2677
 
2880
2678
  /**
@@ -3199,30 +2997,17 @@ abstract class CoreStore extends Service {
3199
2997
 
3200
2998
  if (ENV.DS_WARN_ON_UNKNOWN_KEYS) {
3201
2999
  let unknownAttributes, unknownRelationships;
3202
- if (CUSTOM_MODEL_CLASS) {
3203
- let relationships = this.getSchemaDefinitionService().relationshipsDefinitionFor(modelName);
3204
- let attributes = this.getSchemaDefinitionService().attributesDefinitionFor(modelName);
3205
- // Check unknown attributes
3206
- unknownAttributes = Object.keys(data.attributes || {}).filter((key) => {
3207
- return !attributes[key];
3208
- });
3209
-
3210
- // Check unknown relationships
3211
- unknownRelationships = Object.keys(data.relationships || {}).filter((key) => {
3212
- return !relationships[key];
3213
- });
3214
- } else {
3215
- let modelClass = this.modelFor(modelName);
3216
- // Check unknown attributes
3217
- unknownAttributes = Object.keys(data.attributes || {}).filter((key) => {
3218
- return !get(modelClass, 'fields').has(key);
3219
- });
3220
-
3221
- // Check unknown relationships
3222
- unknownRelationships = Object.keys(data.relationships || {}).filter((key) => {
3223
- return !get(modelClass, 'fields').has(key);
3224
- });
3225
- }
3000
+ let relationships = this.getSchemaDefinitionService().relationshipsDefinitionFor(modelName);
3001
+ let attributes = this.getSchemaDefinitionService().attributesDefinitionFor(modelName);
3002
+ // Check unknown attributes
3003
+ unknownAttributes = Object.keys(data.attributes || {}).filter((key) => {
3004
+ return !attributes[key];
3005
+ });
3006
+
3007
+ // Check unknown relationships
3008
+ unknownRelationships = Object.keys(data.relationships || {}).filter((key) => {
3009
+ return !relationships[key];
3010
+ });
3226
3011
  let unknownAttributesMessage = `The payload for '${modelName}' contains these unknown attributes: ${unknownAttributes}. Make sure they've been defined in your model.`;
3227
3012
  warn(unknownAttributesMessage, unknownAttributes.length === 0, {
3228
3013
  id: 'ds.store.unknown-keys-in-payload',
@@ -3352,38 +3137,26 @@ abstract class CoreStore extends Service {
3352
3137
  }
3353
3138
 
3354
3139
  serializeRecord(record: RecordInstance, options?: Dict<unknown>): unknown {
3355
- if (CUSTOM_MODEL_CLASS) {
3356
- let identifier = recordIdentifierFor(record);
3357
- let internalModel = internalModelFactoryFor(this).peek(identifier);
3358
- // TODO we used to check if the record was destroyed here
3359
- return internalModel!.createSnapshot(options).serialize(options);
3360
- }
3361
-
3362
- assert('serializeRecord is only available when CUSTOM_MODEL_CLASS ff is on', false);
3140
+ let identifier = recordIdentifierFor(record);
3141
+ let internalModel = internalModelFactoryFor(this).peek(identifier);
3142
+ // TODO we used to check if the record was destroyed here
3143
+ return internalModel!.createSnapshot(options).serialize(options);
3363
3144
  }
3364
3145
 
3365
3146
  saveRecord(record: RecordInstance, options?: Dict<unknown>): RSVP.Promise<RecordInstance> {
3366
- if (CUSTOM_MODEL_CLASS) {
3367
- let identifier = recordIdentifierFor(record);
3368
- let internalModel = internalModelFactoryFor(this).peek(identifier);
3369
- // TODO we used to check if the record was destroyed here
3370
- // Casting can be removed once REQUEST_SERVICE ff is turned on
3371
- // because a `Record` is provided there will always be a matching internalModel
3372
- return (internalModel!.save(options) as RSVP.Promise<void>).then(() => record);
3373
- }
3374
-
3375
- assert('saveRecord is only available when CUSTOM_MODEL_CLASS ff is on');
3147
+ let identifier = recordIdentifierFor(record);
3148
+ let internalModel = internalModelFactoryFor(this).peek(identifier);
3149
+ // TODO we used to check if the record was destroyed here
3150
+ // Casting can be removed once REQUEST_SERVICE ff is turned on
3151
+ // because a `Record` is provided there will always be a matching internalModel
3152
+ return (internalModel!.save(options) as RSVP.Promise<void>).then(() => record);
3376
3153
  }
3377
3154
 
3378
3155
  relationshipReferenceFor(identifier: RecordIdentifier, key: string): BelongsToReference | HasManyReference {
3379
- if (CUSTOM_MODEL_CLASS) {
3380
- let stableIdentifier = identifierCacheFor(this).getOrCreateRecordIdentifier(identifier);
3381
- let internalModel = internalModelFactoryFor(this).peek(stableIdentifier);
3382
- // TODO we used to check if the record was destroyed here
3383
- return internalModel!.referenceFor(null, key);
3384
- }
3385
-
3386
- assert('relationshipReferenceFor is only available when CUSTOM_MODEL_CLASS ff is on', false);
3156
+ let stableIdentifier = identifierCacheFor(this).getOrCreateRecordIdentifier(identifier);
3157
+ let internalModel = internalModelFactoryFor(this).peek(stableIdentifier);
3158
+ // TODO we used to check if the record was destroyed here
3159
+ return internalModel!.referenceFor(null, key);
3387
3160
  }
3388
3161
 
3389
3162
  /**
@@ -3637,10 +3410,6 @@ abstract class CoreStore extends Service {
3637
3410
  for an `App.ApplicationSerializer` (the default serializer for
3638
3411
  your entire application).
3639
3412
 
3640
- if no `App.ApplicationSerializer` is found, it will attempt
3641
- to get the `defaultSerializer` from the `PersonAdapter`
3642
- (`adapterFor('person')`).
3643
-
3644
3413
  If a serializer cannot be found on the adapter, it will fall back
3645
3414
  to an instance of `JSONSerializer`.
3646
3415
 
@@ -3708,31 +3477,6 @@ abstract class CoreStore extends Service {
3708
3477
  }
3709
3478
 
3710
3479
  let serializerName;
3711
- if (DEPRECATE_DEFAULT_SERIALIZER) {
3712
- // no model specific serializer or application serializer, check for the `defaultSerializer`
3713
- // property defined on the adapter
3714
- let adapter = this.adapterFor(modelName);
3715
- serializerName = get(adapter, 'defaultSerializer');
3716
-
3717
- deprecate(
3718
- `store.serializerFor("${modelName}") resolved the "${serializerName}" serializer via the deprecated \`adapter.defaultSerializer\` property.\n\n\tPreviously, if no application or type-specific serializer was specified, the store would attempt to lookup a serializer via the \`defaultSerializer\` property on the type's adapter. This behavior is deprecated in favor of explicitly defining a type-specific serializer or application serializer`,
3719
- !serializerName,
3720
- {
3721
- id: 'ember-data:default-serializer',
3722
- until: '4.0',
3723
- url: 'https://deprecations.emberjs.com/ember-data/v3.x/#toc_ember-data-default-serializers',
3724
- for: '@ember-data/store',
3725
- since: {
3726
- available: '3.15',
3727
- enabled: '3.15',
3728
- },
3729
- }
3730
- );
3731
-
3732
- serializer = serializerName
3733
- ? _serializerCache[serializerName] || owner.lookup(`serializer:${serializerName}`)
3734
- : undefined;
3735
- }
3736
3480
 
3737
3481
  if (DEPRECATE_LEGACY_TEST_REGISTRATIONS) {
3738
3482
  // in production this is handled by the re-export
@@ -3763,49 +3507,10 @@ abstract class CoreStore extends Service {
3763
3507
  }
3764
3508
  }
3765
3509
 
3766
- if (DEPRECATE_DEFAULT_SERIALIZER) {
3767
- // final fallback, no model specific serializer, no application serializer, no
3768
- // `serializer` property on store: use the convenience JSONSerializer
3769
- serializer = _serializerCache['-default'] || owner.lookup('serializer:-default');
3770
- if (DEBUG && HAS_EMBER_DATA_PACKAGE && HAS_SERIALIZER_PACKAGE && serializer === undefined) {
3771
- const JSONSerializer = require('@ember-data/serializer/json').default;
3772
- owner.register('serializer:-default', JSONSerializer);
3773
- serializer = owner.lookup('serializer:-default');
3774
-
3775
- serializer && deprecateTestRegistration('serializer', '-default');
3776
- }
3777
-
3778
- deprecate(
3779
- `store.serializerFor("${modelName}") resolved the "-default" serializer via the deprecated "-default" lookup fallback.\n\n\tPreviously, when no type-specific serializer, application serializer, or adapter.defaultSerializer had been defined by the app, the "-default" serializer would be used which defaulted to the \`JSONSerializer\`. This behavior is deprecated in favor of explicitly defining an application or type-specific serializer`,
3780
- !serializer,
3781
- {
3782
- id: 'ember-data:default-serializer',
3783
- until: '4.0',
3784
- url: 'https://deprecations.emberjs.com/ember-data/v3.x/#toc_ember-data-default-serializers',
3785
- for: '@ember-data/store',
3786
- since: {
3787
- available: '3.15',
3788
- enabled: '3.15',
3789
- },
3790
- }
3791
- );
3792
-
3793
- assert(
3794
- `No serializer was found for '${modelName}' and no 'application' serializer was found as a fallback`,
3795
- serializer !== undefined
3796
- );
3797
-
3798
- set(serializer, 'store', this);
3799
- _serializerCache[normalizedModelName] = serializer;
3800
- _serializerCache['-default'] = serializer;
3801
-
3802
- return serializer;
3803
- } else {
3804
- assert(
3805
- `No serializer was found for '${modelName}' and no 'application' serializer was found as a fallback`,
3806
- serializer !== undefined
3807
- );
3808
- }
3510
+ assert(
3511
+ `No serializer was found for '${modelName}' and no 'application' serializer was found as a fallback`,
3512
+ serializer !== undefined
3513
+ );
3809
3514
  }
3810
3515
 
3811
3516
  destroy() {
@@ -3934,73 +3639,6 @@ if (DEPRECATE_DEFAULT_ADAPTER) {
3934
3639
 
3935
3640
  export default CoreStore;
3936
3641
 
3937
- function _commit(adapter, store, operation, snapshot) {
3938
- let internalModel = snapshot._internalModel;
3939
- let modelName = snapshot.modelName;
3940
- let modelClass = store.modelFor(modelName);
3941
- assert(`You tried to update a record but you have no adapter (for ${modelName})`, adapter);
3942
- assert(
3943
- `You tried to update a record but your adapter (for ${modelName}) does not implement '${operation}'`,
3944
- typeof adapter[operation] === 'function'
3945
- );
3946
-
3947
- let promise = Promise.resolve().then(() => adapter[operation](store, modelClass, snapshot));
3948
- let serializer = store.serializerFor(modelName);
3949
- let label = `DS: Extract and notify about ${operation} completion of ${internalModel}`;
3950
-
3951
- promise = guardDestroyedStore(promise, store, label);
3952
- promise = _guard(promise, _bind(_objectIsAlive, internalModel));
3953
-
3954
- return promise.then(
3955
- (adapterPayload) => {
3956
- /*
3957
- Note to future spelunkers hoping to optimize.
3958
- We rely on this `run` to create a run loop if needed
3959
- that `store._push` and `store.didSaveRecord` will both share.
3960
-
3961
- We use `join` because it is often the case that we
3962
- have an outer run loop available still from the first
3963
- call to `store._push`;
3964
- */
3965
- store._backburner.join(() => {
3966
- let payload, data, sideloaded;
3967
- if (adapterPayload) {
3968
- payload = normalizeResponseHelper(serializer, store, modelClass, adapterPayload, snapshot.id, operation);
3969
- if (payload.included) {
3970
- sideloaded = payload.included;
3971
- }
3972
- data = payload.data;
3973
- }
3974
- store.didSaveRecord(internalModel, { data }, operation);
3975
- // seems risky, but if the tests pass might be fine?
3976
- if (sideloaded) {
3977
- store._push({ data: null, included: sideloaded });
3978
- }
3979
- });
3980
-
3981
- return internalModel;
3982
- },
3983
- function (error) {
3984
- if (error && error.isAdapterError === true && error.code === 'InvalidError') {
3985
- let parsedErrors;
3986
-
3987
- if (typeof serializer.extractErrors === 'function') {
3988
- parsedErrors = serializer.extractErrors(store, modelClass, error, snapshot.id);
3989
- } else {
3990
- parsedErrors = errorsArrayToHash(error.errors);
3991
- }
3992
-
3993
- store.recordWasInvalid(internalModel, parsedErrors, error);
3994
- } else {
3995
- store.recordWasError(internalModel, error);
3996
- }
3997
-
3998
- throw error;
3999
- },
4000
- label
4001
- );
4002
- }
4003
-
4004
3642
  let assertDestroyingStore: Function;
4005
3643
  let assertDestroyedStoreOnly: Function;
4006
3644