@ember-data/store 4.4.0 → 4.5.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.
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 +7 -6
  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
@@ -262,7 +262,6 @@ const DirtyState = {
262
262
 
263
263
  rolledBack(internalModel) {
264
264
  internalModel.transitionTo('loaded.saved');
265
- internalModel.triggerLater('rolledBack');
266
265
  },
267
266
 
268
267
  becameInvalid(internalModel) {
@@ -271,7 +270,6 @@ const DirtyState = {
271
270
 
272
271
  rollback(internalModel) {
273
272
  internalModel.rollbackAttributes();
274
- internalModel.triggerLater('ready');
275
273
  },
276
274
  },
277
275
 
@@ -297,9 +295,7 @@ const DirtyState = {
297
295
  internalModel.send('invokeLifecycleCallbacks', this.dirtyType);
298
296
  },
299
297
 
300
- rolledBack(internalModel) {
301
- internalModel.triggerLater('rolledBack');
302
- },
298
+ rolledBack() {},
303
299
 
304
300
  becameInvalid(internalModel) {
305
301
  internalModel.transitionTo('invalid');
@@ -308,7 +304,6 @@ const DirtyState = {
308
304
 
309
305
  becameError(internalModel) {
310
306
  internalModel.transitionTo('uncommitted');
311
- internalModel.triggerLater('becameError', internalModel);
312
307
  },
313
308
  },
314
309
 
@@ -345,16 +340,13 @@ const DirtyState = {
345
340
  rolledBack(internalModel) {
346
341
  clearErrorMessages(internalModel);
347
342
  internalModel.transitionTo('loaded.saved');
348
- internalModel.triggerLater('ready');
349
343
  },
350
344
 
351
345
  becameValid(internalModel) {
352
346
  internalModel.transitionTo('uncommitted');
353
347
  },
354
348
 
355
- invokeLifecycleCallbacks(internalModel) {
356
- internalModel.triggerLater('becameInvalid', internalModel);
357
- },
349
+ invokeLifecycleCallbacks() {},
358
350
  },
359
351
  };
360
352
 
@@ -403,12 +395,10 @@ const createdState = dirtyState({
403
395
 
404
396
  createdState.invalid.rolledBack = function (internalModel) {
405
397
  internalModel.transitionTo('deleted.saved');
406
- internalModel.triggerLater('rolledBack');
407
398
  };
408
399
 
409
400
  createdState.uncommitted.rolledBack = function (internalModel) {
410
401
  internalModel.transitionTo('deleted.saved');
411
- internalModel.triggerLater('rolledBack');
412
402
  };
413
403
 
414
404
  const updatedState = dirtyState({
@@ -433,7 +423,6 @@ createdState.uncommitted.pushedData = function (internalModel) {
433
423
  // TODO @runspired consider where to do this once we kill off state machine
434
424
  internalModel.store._notificationManager.notify(internalModel.identifier, 'identity');
435
425
  internalModel.transitionTo('loaded.updated.uncommitted');
436
- internalModel.triggerLater('didLoad');
437
426
  };
438
427
 
439
428
  createdState.uncommitted.propertyWasReset = function () {};
@@ -458,7 +447,6 @@ updatedState.uncommitted.deleteRecord = function (internalModel) {
458
447
  updatedState.invalid.rolledBack = function (internalModel) {
459
448
  clearErrorMessages(internalModel);
460
449
  internalModel.transitionTo('loaded.saved');
461
- internalModel.triggerLater('rolledBack');
462
450
  };
463
451
 
464
452
  const RootState = {
@@ -500,13 +488,10 @@ const RootState = {
500
488
 
501
489
  loadedData(internalModel) {
502
490
  internalModel.transitionTo('loaded.created.uncommitted');
503
- internalModel.triggerLater('ready');
504
491
  },
505
492
 
506
493
  pushedData(internalModel) {
507
494
  internalModel.transitionTo('loaded.saved');
508
- internalModel.triggerLater('didLoad');
509
- internalModel.triggerLater('ready');
510
495
  },
511
496
 
512
497
  // Record is already in an empty state, triggering transition to empty here
@@ -533,15 +518,11 @@ const RootState = {
533
518
  // EVENTS
534
519
  pushedData(internalModel) {
535
520
  internalModel.transitionTo('loaded.saved');
536
- internalModel.triggerLater('didLoad');
537
- internalModel.triggerLater('ready');
538
521
  //TODO this seems out of place here
539
522
  internalModel.didCleanError();
540
523
  },
541
524
 
542
- becameError(internalModel) {
543
- internalModel.triggerLater('becameError', internalModel);
544
- },
525
+ becameError() {},
545
526
 
546
527
  notFound(internalModel) {
547
528
  internalModel.transitionTo('empty');
@@ -640,7 +621,6 @@ const RootState = {
640
621
 
641
622
  rollback(internalModel) {
642
623
  internalModel.rollbackAttributes();
643
- internalModel.triggerLater('ready');
644
624
  },
645
625
 
646
626
  pushedData() {},
@@ -649,8 +629,6 @@ const RootState = {
649
629
 
650
630
  rolledBack(internalModel) {
651
631
  internalModel.transitionTo('loaded.saved');
652
- internalModel.triggerLater('ready');
653
- internalModel.triggerLater('rolledBack');
654
632
  },
655
633
  },
656
634
 
@@ -676,12 +654,10 @@ const RootState = {
676
654
 
677
655
  becameError(internalModel) {
678
656
  internalModel.transitionTo('uncommitted');
679
- internalModel.triggerLater('becameError', internalModel);
680
657
  },
681
658
 
682
659
  becameInvalid(internalModel) {
683
660
  internalModel.transitionTo('invalid');
684
- internalModel.triggerLater('becameInvalid', internalModel);
685
661
  },
686
662
  },
687
663
 
@@ -696,10 +672,7 @@ const RootState = {
696
672
  internalModel.removeFromInverseRelationships();
697
673
  },
698
674
 
699
- invokeLifecycleCallbacks(internalModel) {
700
- internalModel.triggerLater('didDelete', internalModel);
701
- internalModel.triggerLater('didCommit', internalModel);
702
- },
675
+ invokeLifecycleCallbacks() {},
703
676
 
704
677
  willCommit() {},
705
678
  didCommit() {},
@@ -727,7 +700,6 @@ const RootState = {
727
700
  rolledBack(internalModel) {
728
701
  clearErrorMessages(internalModel);
729
702
  internalModel.transitionTo('loaded.saved');
730
- internalModel.triggerLater('ready');
731
703
  },
732
704
 
733
705
  becameValid(internalModel) {
@@ -736,15 +708,7 @@ const RootState = {
736
708
  },
737
709
  },
738
710
 
739
- invokeLifecycleCallbacks(internalModel, dirtyType) {
740
- if (dirtyType === 'created') {
741
- internalModel.triggerLater('didCreate', internalModel);
742
- } else {
743
- internalModel.triggerLater('didUpdate', internalModel);
744
- }
745
-
746
- internalModel.triggerLater('didCommit', internalModel);
747
- },
711
+ invokeLifecycleCallbacks() {},
748
712
  };
749
713
 
750
714
  function wireState(object, parent, name) {
@@ -1,10 +1,11 @@
1
- import ArrayProxy from '@ember/array/proxy';
2
1
  import { deprecate } from '@ember/debug';
2
+ import type ComputedProperty from '@ember/object/computed';
3
3
  import { reads } from '@ember/object/computed';
4
- import PromiseProxyMixin from '@ember/object/promise-proxy-mixin';
5
- import ObjectProxy from '@ember/object/proxy';
6
4
 
7
- import { Promise } from 'rsvp';
5
+ import { resolve } from 'rsvp';
6
+
7
+ import type { Dict } from '../ts-interfaces/utils';
8
+ import { PromiseArrayProxy, PromiseObjectProxy } from './promise-proxy-base';
8
9
 
9
10
  /**
10
11
  @module @ember-data/store
@@ -41,9 +42,20 @@ import { Promise } from 'rsvp';
41
42
  @extends Ember.ArrayProxy
42
43
  @uses Ember.PromiseProxyMixin
43
44
  */
44
- export const PromiseArray = ArrayProxy.extend(PromiseProxyMixin, {
45
- meta: reads('content.meta'),
46
- });
45
+ interface EmberNativeArrayLike<T> {
46
+ length: number | ComputedProperty<number>;
47
+ objectAt(idx: number): T | undefined;
48
+ }
49
+ interface EmberArrayProxyLike<T> {
50
+ length: number | ComputedProperty<number>;
51
+ objectAtContent(idx: number): T | undefined;
52
+ }
53
+ type EmberArrayLike<T> = EmberNativeArrayLike<T> | EmberArrayProxyLike<T>;
54
+
55
+ export class PromiseArray<I, T extends EmberArrayLike<I>> extends PromiseArrayProxy<I, T> {
56
+ @reads('content.meta')
57
+ declare meta?: Dict<unknown>;
58
+ }
47
59
 
48
60
  /**
49
61
  A `PromiseObject` is an object that acts like both an `EmberObject`
@@ -76,26 +88,26 @@ export const PromiseArray = ArrayProxy.extend(PromiseProxyMixin, {
76
88
  @extends Ember.ObjectProxy
77
89
  @uses Ember.PromiseProxyMixin
78
90
  */
79
- export let PromiseObject = ObjectProxy.extend(PromiseProxyMixin);
91
+ export { PromiseObjectProxy as PromiseObject };
80
92
 
81
- export function promiseObject(promise, label) {
82
- return PromiseObject.create({
83
- promise: Promise.resolve(promise, label),
84
- });
93
+ export function promiseObject<T>(promise: Promise<T>, label?: string): PromiseObjectProxy<T> {
94
+ return PromiseObjectProxy.create({
95
+ promise: resolve(promise, label),
96
+ }) as PromiseObjectProxy<T>;
85
97
  }
86
98
 
87
- export function promiseArray(promise, label) {
99
+ export function promiseArray<I, T extends EmberArrayLike<I>>(promise: Promise<T>, label?: string): PromiseArray<I, T> {
88
100
  return PromiseArray.create({
89
- promise: Promise.resolve(promise, label),
90
- });
101
+ promise: resolve(promise, label),
102
+ }) as unknown as PromiseArray<I, T>;
91
103
  }
92
104
 
93
105
  // constructor is accessed in some internals but not including it in the copyright for the deprecation
94
106
  const ALLOWABLE_METHODS = ['constructor', 'then', 'catch', 'finally'];
95
107
 
96
- export function deprecatedPromiseObject(promise) {
108
+ export function deprecatedPromiseObject<T>(promise: PromiseObjectProxy<T>): PromiseObjectProxy<T> {
97
109
  const handler = {
98
- get(target, prop) {
110
+ get(target: object, prop: string, receiver?: object): unknown {
99
111
  if (!ALLOWABLE_METHODS.includes(prop)) {
100
112
  deprecate(
101
113
  `Accessing ${prop} is deprecated. Only available methods to access on a promise returned from model.save() are .then, .catch and .finally`,
@@ -112,11 +124,9 @@ export function deprecatedPromiseObject(promise) {
112
124
  );
113
125
  }
114
126
 
115
- /* global Reflect */
116
- return Reflect.get(...arguments).bind(target);
127
+ return (Reflect.get(target, prop, receiver) as Function).bind(target);
117
128
  },
118
129
  };
119
130
 
120
- /* global Proxy */
121
- return new Proxy(promise, handler);
131
+ return new Proxy(promise, handler) as PromiseObjectProxy<T>;
122
132
  }
@@ -0,0 +1,7 @@
1
+ import ArrayProxy from '@ember/array/proxy';
2
+ import PromiseProxyMixin from '@ember/object/promise-proxy-mixin';
3
+ import ObjectProxy from '@ember/object/proxy';
4
+
5
+ export const PromiseArrayProxy = ArrayProxy.extend(PromiseProxyMixin);
6
+
7
+ export const PromiseObjectProxy = ObjectProxy.extend(PromiseProxyMixin);
@@ -4,37 +4,39 @@
4
4
 
5
5
  import { A } from '@ember/array';
6
6
  import { assert } from '@ember/debug';
7
- import { get, set } from '@ember/object';
7
+ import { set } from '@ember/object';
8
8
  import { _backburner as emberBackburner } from '@ember/runloop';
9
9
  import { DEBUG } from '@glimmer/env';
10
10
 
11
- import isStableIdentifier from '../identifiers/is-stable-identifier';
11
+ // import isStableIdentifier from '../identifiers/is-stable-identifier';
12
+ import type { CollectionResourceDocument, Meta } from '../ts-interfaces/ember-data-json-api';
13
+ import type { StableRecordIdentifier } from '../ts-interfaces/identifier';
14
+ import type { Dict } from '../ts-interfaces/utils';
15
+ import type CoreStore from './core-store';
12
16
  import { AdapterPopulatedRecordArray, RecordArray } from './record-arrays';
13
17
  import { internalModelFactoryFor } from './store/internal-model-factory';
14
18
  import WeakCache from './weak-cache';
15
19
 
16
- const RecordArraysCache = new WeakCache(DEBUG ? 'record-arrays' : '');
20
+ const RecordArraysCache = new WeakCache<StableRecordIdentifier, Set<RecordArray>>(DEBUG ? 'record-arrays' : '');
17
21
  RecordArraysCache._generator = () => new Set();
18
- export function recordArraysForIdentifier(identifierOrInternalModel) {
19
- return RecordArraysCache.lookup(identifierOrInternalModel);
22
+ export function recordArraysForIdentifier(identifier: StableRecordIdentifier): Set<RecordArray> {
23
+ return RecordArraysCache.lookup(identifier);
20
24
  }
21
25
 
22
- const pendingForIdentifier = new Set([]);
26
+ const pendingForIdentifier: Set<StableRecordIdentifier> = new Set([]);
23
27
 
24
- function getIdentifier(identifierOrInternalModel) {
25
- let i = identifierOrInternalModel;
26
- if (!isStableIdentifier(identifierOrInternalModel)) {
27
- // identifier may actually be an internalModel
28
- // but during materialization we will get an identifier that
29
- // has already been removed from the identifiers cache yet
30
- // so it will not behave as if stable. This is a bug we should fix.
31
- i = identifierOrInternalModel.identifier || i;
32
- }
28
+ function getIdentifier(identifier: StableRecordIdentifier): StableRecordIdentifier {
29
+ // during dematerialization we will get an identifier that
30
+ // has already been removed from the identifiers cache
31
+ // so it will not behave as if stable. This is a bug we should fix.
32
+ // if (!isStableIdentifier(identifierOrInternalModel)) {
33
+ // console.log({ unstable: i });
34
+ // }
33
35
 
34
- return i;
36
+ return identifier;
35
37
  }
36
38
 
37
- function shouldIncludeInRecordArrays(store, identifier) {
39
+ function shouldIncludeInRecordArrays(store: CoreStore, identifier: StableRecordIdentifier): boolean {
38
40
  const cache = internalModelFactoryFor(store);
39
41
  const internalModel = cache.peek(identifier);
40
42
 
@@ -49,12 +51,19 @@ function shouldIncludeInRecordArrays(store, identifier) {
49
51
  @internal
50
52
  */
51
53
  class RecordArrayManager {
52
- constructor(options) {
54
+ declare store: CoreStore;
55
+ declare isDestroying: boolean;
56
+ declare isDestroyed: boolean;
57
+ declare _liveRecordArrays: Dict<RecordArray>;
58
+ declare _pendingIdentifiers: Dict<StableRecordIdentifier[]>;
59
+ declare _adapterPopulatedRecordArrays: RecordArray[];
60
+
61
+ constructor(options: { store: CoreStore }) {
53
62
  this.store = options.store;
54
63
  this.isDestroying = false;
55
64
  this.isDestroyed = false;
56
- this._liveRecordArrays = Object.create(null);
57
- this._pendingIdentifiers = Object.create(null);
65
+ this._liveRecordArrays = Object.create(null) as Dict<RecordArray>;
66
+ this._pendingIdentifiers = Object.create(null) as Dict<StableRecordIdentifier[]>;
58
67
  this._adapterPopulatedRecordArrays = [];
59
68
  }
60
69
 
@@ -64,15 +73,15 @@ class RecordArrayManager {
64
73
  * @param {StableIdentifier} param
65
74
  * @return {RecordArray} array
66
75
  */
67
- getRecordArraysForIdentifier(identifier) {
76
+ getRecordArraysForIdentifier(identifier: StableRecordIdentifier): Set<RecordArray> {
68
77
  return recordArraysForIdentifier(identifier);
69
78
  }
70
79
 
71
- _flushPendingIdentifiersForModelName(modelName, identifiers) {
80
+ _flushPendingIdentifiersForModelName(modelName: string, identifiers: StableRecordIdentifier[]): void {
72
81
  if (this.isDestroying || this.isDestroyed) {
73
82
  return;
74
83
  }
75
- let modelsToRemove = [];
84
+ let identifiersToRemove: StableRecordIdentifier[] = [];
76
85
 
77
86
  for (let j = 0; j < identifiers.length; j++) {
78
87
  let i = identifiers[j];
@@ -82,7 +91,7 @@ class RecordArrayManager {
82
91
  // build up a set of models to ensure we have purged correctly;
83
92
  let isIncluded = shouldIncludeInRecordArrays(this.store, i);
84
93
  if (!isIncluded) {
85
- modelsToRemove.push(i);
94
+ identifiersToRemove.push(i);
86
95
  }
87
96
  }
88
97
 
@@ -94,30 +103,33 @@ class RecordArrayManager {
94
103
  }
95
104
 
96
105
  // process adapterPopulatedRecordArrays
97
- if (modelsToRemove.length > 0) {
98
- removeFromAdapterPopulatedRecordArrays(this.store, modelsToRemove);
106
+ if (identifiersToRemove.length > 0) {
107
+ removeFromAdapterPopulatedRecordArrays(this.store, identifiersToRemove);
99
108
  }
100
109
  }
101
110
 
102
111
  _flush() {
103
112
  let pending = this._pendingIdentifiers;
104
- this._pendingIdentifiers = Object.create(null);
113
+ this._pendingIdentifiers = Object.create(null) as Dict<StableRecordIdentifier[]>;
105
114
 
106
115
  for (let modelName in pending) {
107
- this._flushPendingIdentifiersForModelName(modelName, pending[modelName]);
116
+ this._flushPendingIdentifiersForModelName(modelName, pending[modelName]!);
108
117
  }
109
118
  }
110
119
 
111
- _syncLiveRecordArray(array, modelName) {
120
+ _syncLiveRecordArray(array: RecordArray, modelName: string) {
112
121
  assert(
113
122
  `recordArrayManger.syncLiveRecordArray expects modelName not modelClass as the second param`,
114
123
  typeof modelName === 'string'
115
124
  );
116
125
  let pending = this._pendingIdentifiers[modelName];
117
- let hasPendingChanges = Array.isArray(pending);
118
- let hasNoPotentialDeletions = !hasPendingChanges || pending.length === 0;
126
+
127
+ if (!Array.isArray(pending)) {
128
+ return;
129
+ }
130
+ let hasNoPotentialDeletions = pending.length === 0;
119
131
  let map = internalModelFactoryFor(this.store).modelMapFor(modelName);
120
- let hasNoInsertionsOrRemovals = get(map, 'length') === get(array, 'length');
132
+ let hasNoInsertionsOrRemovals = map.length === array.length;
121
133
 
122
134
  /*
123
135
  Ideally the recordArrayManager has knowledge of the changes to be applied to
@@ -129,28 +141,26 @@ class RecordArrayManager {
129
141
  return;
130
142
  }
131
143
 
132
- if (hasPendingChanges) {
133
- this._flushPendingIdentifiersForModelName(modelName, pending);
134
- delete this._pendingIdentifiers[modelName];
135
- }
144
+ this._flushPendingIdentifiersForModelName(modelName, pending);
145
+ delete this._pendingIdentifiers[modelName];
136
146
 
137
147
  let identifiers = this._visibleIdentifiersByType(modelName);
138
- let modelsToAdd = [];
148
+ let identifiersToAdd: StableRecordIdentifier[] = [];
139
149
  for (let i = 0; i < identifiers.length; i++) {
140
150
  let identifier = identifiers[i];
141
151
  let recordArrays = recordArraysForIdentifier(identifier);
142
152
  if (recordArrays.has(array) === false) {
143
153
  recordArrays.add(array);
144
- modelsToAdd.push(identifier);
154
+ identifiersToAdd.push(identifier);
145
155
  }
146
156
  }
147
157
 
148
- if (modelsToAdd.length) {
149
- array._pushIdentifiers(modelsToAdd);
158
+ if (identifiersToAdd.length) {
159
+ array._pushIdentifiers(identifiersToAdd);
150
160
  }
151
161
  }
152
162
 
153
- _didUpdateAll(modelName) {
163
+ _didUpdateAll(modelName: string): void {
154
164
  let recordArray = this._liveRecordArrays[modelName];
155
165
  if (recordArray) {
156
166
  set(recordArray, 'isUpdating', false);
@@ -166,7 +176,7 @@ class RecordArrayManager {
166
176
  @param {String} modelName
167
177
  @return {RecordArray}
168
178
  */
169
- liveRecordArrayFor(modelName) {
179
+ liveRecordArrayFor(modelName: string): RecordArray {
170
180
  assert(
171
181
  `recordArrayManger.liveRecordArrayFor expects modelName not modelClass as the param`,
172
182
  typeof modelName === 'string'
@@ -188,9 +198,9 @@ class RecordArrayManager {
188
198
  return array;
189
199
  }
190
200
 
191
- _visibleIdentifiersByType(modelName) {
201
+ _visibleIdentifiersByType(modelName: string) {
192
202
  let all = internalModelFactoryFor(this.store).modelMapFor(modelName).recordIdentifiers;
193
- let visible = [];
203
+ let visible: StableRecordIdentifier[] = [];
194
204
  for (let i = 0; i < all.length; i++) {
195
205
  let identifier = all[i];
196
206
  let shouldInclude = shouldIncludeInRecordArrays(this.store, identifier);
@@ -211,7 +221,7 @@ class RecordArrayManager {
211
221
  @param {Array} [identifiers]
212
222
  @return {RecordArray}
213
223
  */
214
- createRecordArray(modelName, identifiers) {
224
+ createRecordArray(modelName: string, identifiers: StableRecordIdentifier[] = []): RecordArray {
215
225
  assert(
216
226
  `recordArrayManger.createRecordArray expects modelName not modelClass as the param`,
217
227
  typeof modelName === 'string'
@@ -241,13 +251,18 @@ class RecordArrayManager {
241
251
  @param {Object} query
242
252
  @return {AdapterPopulatedRecordArray}
243
253
  */
244
- createAdapterPopulatedRecordArray(modelName, query, identifiers, payload) {
254
+ createAdapterPopulatedRecordArray(
255
+ modelName: string,
256
+ query: Dict<unknown> | undefined,
257
+ identifiers: StableRecordIdentifier[],
258
+ payload?: CollectionResourceDocument
259
+ ): AdapterPopulatedRecordArray {
245
260
  assert(
246
261
  `recordArrayManger.createAdapterPopulatedRecordArray expects modelName not modelClass as the first param, received ${modelName}`,
247
262
  typeof modelName === 'string'
248
263
  );
249
264
 
250
- let array;
265
+ let array: AdapterPopulatedRecordArray;
251
266
  if (Array.isArray(identifiers)) {
252
267
  array = AdapterPopulatedRecordArray.create({
253
268
  modelName,
@@ -257,8 +272,11 @@ class RecordArrayManager {
257
272
  manager: this,
258
273
  isLoaded: true,
259
274
  isUpdating: false,
260
- meta: { ...payload.meta },
261
- links: { ...payload.links },
275
+ // TODO this assign kills the root reference but a deep-copy would be required
276
+ // for both meta and links to actually not be by-ref. We whould likely change
277
+ // this to a dev-only deep-freeze.
278
+ meta: Object.assign({} as Meta, payload!.meta),
279
+ links: Object.assign({}, payload!.links),
262
280
  });
263
281
 
264
282
  this._associateWithRecordArray(identifiers, array);
@@ -266,7 +284,8 @@ class RecordArrayManager {
266
284
  array = AdapterPopulatedRecordArray.create({
267
285
  modelName,
268
286
  query: query,
269
- content: A(),
287
+ content: A<StableRecordIdentifier>(),
288
+ isLoaded: false,
270
289
  store: this.store,
271
290
  manager: this,
272
291
  });
@@ -285,7 +304,7 @@ class RecordArrayManager {
285
304
  @internal
286
305
  @param {RecordArray} array
287
306
  */
288
- unregisterRecordArray(array) {
307
+ unregisterRecordArray(array: RecordArray): void {
289
308
  let modelName = array.modelName;
290
309
 
291
310
  // remove from adapter populated record array
@@ -308,7 +327,7 @@ class RecordArrayManager {
308
327
  * @param {StableIdentifier} identifiers
309
328
  * @param {RecordArray} array
310
329
  */
311
- _associateWithRecordArray(identifiers, array) {
330
+ _associateWithRecordArray(identifiers: StableRecordIdentifier[], array: RecordArray): void {
312
331
  for (let i = 0, l = identifiers.length; i < l; i++) {
313
332
  let identifier = identifiers[i];
314
333
  identifier = getIdentifier(identifier);
@@ -321,7 +340,7 @@ class RecordArrayManager {
321
340
  @method recordDidChange
322
341
  @internal
323
342
  */
324
- recordDidChange(identifier) {
343
+ recordDidChange(identifier: StableRecordIdentifier): void {
325
344
  if (this.isDestroying || this.isDestroyed) {
326
345
  return;
327
346
  }
@@ -340,22 +359,26 @@ class RecordArrayManager {
340
359
  return;
341
360
  }
342
361
 
362
+ // TODO do we still need this schedule?
363
+ // eslint-disable-next-line @typescript-eslint/unbound-method
343
364
  emberBackburner.schedule('actions', this, this._flush);
344
365
  }
345
366
 
346
367
  willDestroy() {
347
- Object.keys(this._liveRecordArrays).forEach((modelName) => this._liveRecordArrays[modelName].destroy());
368
+ Object.keys(this._liveRecordArrays).forEach((modelName) => this._liveRecordArrays[modelName]!.destroy());
348
369
  this._adapterPopulatedRecordArrays.forEach((entry) => entry.destroy());
349
370
  this.isDestroyed = true;
350
371
  }
351
372
 
352
373
  destroy() {
353
374
  this.isDestroying = true;
375
+ // TODO do we still need this schedule?
376
+ // eslint-disable-next-line @typescript-eslint/unbound-method
354
377
  emberBackburner.schedule('actions', this, this.willDestroy);
355
378
  }
356
379
  }
357
380
 
358
- function removeFromArray(array, item) {
381
+ function removeFromArray(array: RecordArray[], item: RecordArray): boolean {
359
382
  let index = array.indexOf(item);
360
383
 
361
384
  if (index !== -1) {
@@ -366,9 +389,13 @@ function removeFromArray(array, item) {
366
389
  return false;
367
390
  }
368
391
 
369
- function updateLiveRecordArray(store, recordArray, identifiers) {
370
- let identifiersToAdd = [];
371
- let identifiersToRemove = [];
392
+ function updateLiveRecordArray(
393
+ store: CoreStore,
394
+ recordArray: RecordArray,
395
+ identifiers: StableRecordIdentifier[]
396
+ ): void {
397
+ let identifiersToAdd: StableRecordIdentifier[] = [];
398
+ let identifiersToRemove: StableRecordIdentifier[] = [];
372
399
 
373
400
  for (let i = 0; i < identifiers.length; i++) {
374
401
  let identifier = identifiers[i];
@@ -396,13 +423,13 @@ function updateLiveRecordArray(store, recordArray, identifiers) {
396
423
  }
397
424
  }
398
425
 
399
- function removeFromAdapterPopulatedRecordArrays(store, identifiers) {
426
+ function removeFromAdapterPopulatedRecordArrays(store: CoreStore, identifiers: StableRecordIdentifier[]): void {
400
427
  for (let i = 0; i < identifiers.length; i++) {
401
428
  removeFromAll(store, identifiers[i]);
402
429
  }
403
430
  }
404
431
 
405
- function removeFromAll(store, identifier) {
432
+ function removeFromAll(store: CoreStore, identifier: StableRecordIdentifier): void {
406
433
  identifier = getIdentifier(identifier);
407
434
  const recordArrays = recordArraysForIdentifier(identifier);
408
435