@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
@@ -1,11 +1,10 @@
1
+ import ArrayProxy from '@ember/array/proxy';
1
2
  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';
4
6
 
5
- import { resolve } from 'rsvp';
6
-
7
- import type { Dict } from '../ts-interfaces/utils';
8
- import { PromiseArrayProxy, PromiseObjectProxy } from './promise-proxy-base';
7
+ import { Promise } from 'rsvp';
9
8
 
10
9
  /**
11
10
  @module @ember-data/store
@@ -42,20 +41,9 @@ import { PromiseArrayProxy, PromiseObjectProxy } from './promise-proxy-base';
42
41
  @extends Ember.ArrayProxy
43
42
  @uses Ember.PromiseProxyMixin
44
43
  */
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
- }
44
+ export const PromiseArray = ArrayProxy.extend(PromiseProxyMixin, {
45
+ meta: reads('content.meta'),
46
+ });
59
47
 
60
48
  /**
61
49
  A `PromiseObject` is an object that acts like both an `EmberObject`
@@ -88,26 +76,26 @@ export class PromiseArray<I, T extends EmberArrayLike<I>> extends PromiseArrayPr
88
76
  @extends Ember.ObjectProxy
89
77
  @uses Ember.PromiseProxyMixin
90
78
  */
91
- export { PromiseObjectProxy as PromiseObject };
79
+ export let PromiseObject = ObjectProxy.extend(PromiseProxyMixin);
92
80
 
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>;
81
+ export function promiseObject(promise, label) {
82
+ return PromiseObject.create({
83
+ promise: Promise.resolve(promise, label),
84
+ });
97
85
  }
98
86
 
99
- export function promiseArray<I, T extends EmberArrayLike<I>>(promise: Promise<T>, label?: string): PromiseArray<I, T> {
87
+ export function promiseArray(promise, label) {
100
88
  return PromiseArray.create({
101
- promise: resolve(promise, label),
102
- }) as unknown as PromiseArray<I, T>;
89
+ promise: Promise.resolve(promise, label),
90
+ });
103
91
  }
104
92
 
105
93
  // constructor is accessed in some internals but not including it in the copyright for the deprecation
106
94
  const ALLOWABLE_METHODS = ['constructor', 'then', 'catch', 'finally'];
107
95
 
108
- export function deprecatedPromiseObject<T>(promise: PromiseObjectProxy<T>): PromiseObjectProxy<T> {
96
+ export function deprecatedPromiseObject(promise) {
109
97
  const handler = {
110
- get(target: object, prop: string, receiver?: object): unknown {
98
+ get(target, prop) {
111
99
  if (!ALLOWABLE_METHODS.includes(prop)) {
112
100
  deprecate(
113
101
  `Accessing ${prop} is deprecated. Only available methods to access on a promise returned from model.save() are .then, .catch and .finally`,
@@ -124,9 +112,11 @@ export function deprecatedPromiseObject<T>(promise: PromiseObjectProxy<T>): Prom
124
112
  );
125
113
  }
126
114
 
127
- return (Reflect.get(target, prop, receiver) as Function).bind(target);
115
+ /* global Reflect */
116
+ return Reflect.get(...arguments).bind(target);
128
117
  },
129
118
  };
130
119
 
131
- return new Proxy(promise, handler) as PromiseObjectProxy<T>;
120
+ /* global Proxy */
121
+ return new Proxy(promise, handler);
132
122
  }
@@ -4,39 +4,37 @@
4
4
 
5
5
  import { A } from '@ember/array';
6
6
  import { assert } from '@ember/debug';
7
- import { set } from '@ember/object';
7
+ import { get, 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';
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';
11
+ import isStableIdentifier from '../identifiers/is-stable-identifier';
16
12
  import { AdapterPopulatedRecordArray, RecordArray } from './record-arrays';
17
13
  import { internalModelFactoryFor } from './store/internal-model-factory';
18
14
  import WeakCache from './weak-cache';
19
15
 
20
- const RecordArraysCache = new WeakCache<StableRecordIdentifier, Set<RecordArray>>(DEBUG ? 'record-arrays' : '');
16
+ const RecordArraysCache = new WeakCache(DEBUG ? 'record-arrays' : '');
21
17
  RecordArraysCache._generator = () => new Set();
22
- export function recordArraysForIdentifier(identifier: StableRecordIdentifier): Set<RecordArray> {
23
- return RecordArraysCache.lookup(identifier);
18
+ export function recordArraysForIdentifier(identifierOrInternalModel) {
19
+ return RecordArraysCache.lookup(identifierOrInternalModel);
24
20
  }
25
21
 
26
- const pendingForIdentifier: Set<StableRecordIdentifier> = new Set([]);
22
+ const pendingForIdentifier = new Set([]);
27
23
 
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
- // }
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
+ }
35
33
 
36
- return identifier;
34
+ return i;
37
35
  }
38
36
 
39
- function shouldIncludeInRecordArrays(store: CoreStore, identifier: StableRecordIdentifier): boolean {
37
+ function shouldIncludeInRecordArrays(store, identifier) {
40
38
  const cache = internalModelFactoryFor(store);
41
39
  const internalModel = cache.peek(identifier);
42
40
 
@@ -51,19 +49,12 @@ function shouldIncludeInRecordArrays(store: CoreStore, identifier: StableRecordI
51
49
  @internal
52
50
  */
53
51
  class RecordArrayManager {
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 }) {
52
+ constructor(options) {
62
53
  this.store = options.store;
63
54
  this.isDestroying = false;
64
55
  this.isDestroyed = false;
65
- this._liveRecordArrays = Object.create(null) as Dict<RecordArray>;
66
- this._pendingIdentifiers = Object.create(null) as Dict<StableRecordIdentifier[]>;
56
+ this._liveRecordArrays = Object.create(null);
57
+ this._pendingIdentifiers = Object.create(null);
67
58
  this._adapterPopulatedRecordArrays = [];
68
59
  }
69
60
 
@@ -73,15 +64,15 @@ class RecordArrayManager {
73
64
  * @param {StableIdentifier} param
74
65
  * @return {RecordArray} array
75
66
  */
76
- getRecordArraysForIdentifier(identifier: StableRecordIdentifier): Set<RecordArray> {
67
+ getRecordArraysForIdentifier(identifier) {
77
68
  return recordArraysForIdentifier(identifier);
78
69
  }
79
70
 
80
- _flushPendingIdentifiersForModelName(modelName: string, identifiers: StableRecordIdentifier[]): void {
71
+ _flushPendingIdentifiersForModelName(modelName, identifiers) {
81
72
  if (this.isDestroying || this.isDestroyed) {
82
73
  return;
83
74
  }
84
- let identifiersToRemove: StableRecordIdentifier[] = [];
75
+ let modelsToRemove = [];
85
76
 
86
77
  for (let j = 0; j < identifiers.length; j++) {
87
78
  let i = identifiers[j];
@@ -91,7 +82,7 @@ class RecordArrayManager {
91
82
  // build up a set of models to ensure we have purged correctly;
92
83
  let isIncluded = shouldIncludeInRecordArrays(this.store, i);
93
84
  if (!isIncluded) {
94
- identifiersToRemove.push(i);
85
+ modelsToRemove.push(i);
95
86
  }
96
87
  }
97
88
 
@@ -103,33 +94,30 @@ class RecordArrayManager {
103
94
  }
104
95
 
105
96
  // process adapterPopulatedRecordArrays
106
- if (identifiersToRemove.length > 0) {
107
- removeFromAdapterPopulatedRecordArrays(this.store, identifiersToRemove);
97
+ if (modelsToRemove.length > 0) {
98
+ removeFromAdapterPopulatedRecordArrays(this.store, modelsToRemove);
108
99
  }
109
100
  }
110
101
 
111
102
  _flush() {
112
103
  let pending = this._pendingIdentifiers;
113
- this._pendingIdentifiers = Object.create(null) as Dict<StableRecordIdentifier[]>;
104
+ this._pendingIdentifiers = Object.create(null);
114
105
 
115
106
  for (let modelName in pending) {
116
- this._flushPendingIdentifiersForModelName(modelName, pending[modelName]!);
107
+ this._flushPendingIdentifiersForModelName(modelName, pending[modelName]);
117
108
  }
118
109
  }
119
110
 
120
- _syncLiveRecordArray(array: RecordArray, modelName: string) {
111
+ _syncLiveRecordArray(array, modelName) {
121
112
  assert(
122
113
  `recordArrayManger.syncLiveRecordArray expects modelName not modelClass as the second param`,
123
114
  typeof modelName === 'string'
124
115
  );
125
116
  let pending = this._pendingIdentifiers[modelName];
126
-
127
- if (!Array.isArray(pending)) {
128
- return;
129
- }
130
- let hasNoPotentialDeletions = pending.length === 0;
117
+ let hasPendingChanges = Array.isArray(pending);
118
+ let hasNoPotentialDeletions = !hasPendingChanges || pending.length === 0;
131
119
  let map = internalModelFactoryFor(this.store).modelMapFor(modelName);
132
- let hasNoInsertionsOrRemovals = map.length === array.length;
120
+ let hasNoInsertionsOrRemovals = get(map, 'length') === get(array, 'length');
133
121
 
134
122
  /*
135
123
  Ideally the recordArrayManager has knowledge of the changes to be applied to
@@ -141,26 +129,28 @@ class RecordArrayManager {
141
129
  return;
142
130
  }
143
131
 
144
- this._flushPendingIdentifiersForModelName(modelName, pending);
145
- delete this._pendingIdentifiers[modelName];
132
+ if (hasPendingChanges) {
133
+ this._flushPendingIdentifiersForModelName(modelName, pending);
134
+ delete this._pendingIdentifiers[modelName];
135
+ }
146
136
 
147
137
  let identifiers = this._visibleIdentifiersByType(modelName);
148
- let identifiersToAdd: StableRecordIdentifier[] = [];
138
+ let modelsToAdd = [];
149
139
  for (let i = 0; i < identifiers.length; i++) {
150
140
  let identifier = identifiers[i];
151
141
  let recordArrays = recordArraysForIdentifier(identifier);
152
142
  if (recordArrays.has(array) === false) {
153
143
  recordArrays.add(array);
154
- identifiersToAdd.push(identifier);
144
+ modelsToAdd.push(identifier);
155
145
  }
156
146
  }
157
147
 
158
- if (identifiersToAdd.length) {
159
- array._pushIdentifiers(identifiersToAdd);
148
+ if (modelsToAdd.length) {
149
+ array._pushIdentifiers(modelsToAdd);
160
150
  }
161
151
  }
162
152
 
163
- _didUpdateAll(modelName: string): void {
153
+ _didUpdateAll(modelName) {
164
154
  let recordArray = this._liveRecordArrays[modelName];
165
155
  if (recordArray) {
166
156
  set(recordArray, 'isUpdating', false);
@@ -176,7 +166,7 @@ class RecordArrayManager {
176
166
  @param {String} modelName
177
167
  @return {RecordArray}
178
168
  */
179
- liveRecordArrayFor(modelName: string): RecordArray {
169
+ liveRecordArrayFor(modelName) {
180
170
  assert(
181
171
  `recordArrayManger.liveRecordArrayFor expects modelName not modelClass as the param`,
182
172
  typeof modelName === 'string'
@@ -198,9 +188,9 @@ class RecordArrayManager {
198
188
  return array;
199
189
  }
200
190
 
201
- _visibleIdentifiersByType(modelName: string) {
191
+ _visibleIdentifiersByType(modelName) {
202
192
  let all = internalModelFactoryFor(this.store).modelMapFor(modelName).recordIdentifiers;
203
- let visible: StableRecordIdentifier[] = [];
193
+ let visible = [];
204
194
  for (let i = 0; i < all.length; i++) {
205
195
  let identifier = all[i];
206
196
  let shouldInclude = shouldIncludeInRecordArrays(this.store, identifier);
@@ -221,7 +211,7 @@ class RecordArrayManager {
221
211
  @param {Array} [identifiers]
222
212
  @return {RecordArray}
223
213
  */
224
- createRecordArray(modelName: string, identifiers: StableRecordIdentifier[] = []): RecordArray {
214
+ createRecordArray(modelName, identifiers) {
225
215
  assert(
226
216
  `recordArrayManger.createRecordArray expects modelName not modelClass as the param`,
227
217
  typeof modelName === 'string'
@@ -251,18 +241,13 @@ class RecordArrayManager {
251
241
  @param {Object} query
252
242
  @return {AdapterPopulatedRecordArray}
253
243
  */
254
- createAdapterPopulatedRecordArray(
255
- modelName: string,
256
- query: Dict<unknown> | undefined,
257
- identifiers: StableRecordIdentifier[],
258
- payload?: CollectionResourceDocument
259
- ): AdapterPopulatedRecordArray {
244
+ createAdapterPopulatedRecordArray(modelName, query, identifiers, payload) {
260
245
  assert(
261
246
  `recordArrayManger.createAdapterPopulatedRecordArray expects modelName not modelClass as the first param, received ${modelName}`,
262
247
  typeof modelName === 'string'
263
248
  );
264
249
 
265
- let array: AdapterPopulatedRecordArray;
250
+ let array;
266
251
  if (Array.isArray(identifiers)) {
267
252
  array = AdapterPopulatedRecordArray.create({
268
253
  modelName,
@@ -272,11 +257,8 @@ class RecordArrayManager {
272
257
  manager: this,
273
258
  isLoaded: true,
274
259
  isUpdating: false,
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),
260
+ meta: { ...payload.meta },
261
+ links: { ...payload.links },
280
262
  });
281
263
 
282
264
  this._associateWithRecordArray(identifiers, array);
@@ -284,8 +266,7 @@ class RecordArrayManager {
284
266
  array = AdapterPopulatedRecordArray.create({
285
267
  modelName,
286
268
  query: query,
287
- content: A<StableRecordIdentifier>(),
288
- isLoaded: false,
269
+ content: A(),
289
270
  store: this.store,
290
271
  manager: this,
291
272
  });
@@ -304,7 +285,7 @@ class RecordArrayManager {
304
285
  @internal
305
286
  @param {RecordArray} array
306
287
  */
307
- unregisterRecordArray(array: RecordArray): void {
288
+ unregisterRecordArray(array) {
308
289
  let modelName = array.modelName;
309
290
 
310
291
  // remove from adapter populated record array
@@ -327,7 +308,7 @@ class RecordArrayManager {
327
308
  * @param {StableIdentifier} identifiers
328
309
  * @param {RecordArray} array
329
310
  */
330
- _associateWithRecordArray(identifiers: StableRecordIdentifier[], array: RecordArray): void {
311
+ _associateWithRecordArray(identifiers, array) {
331
312
  for (let i = 0, l = identifiers.length; i < l; i++) {
332
313
  let identifier = identifiers[i];
333
314
  identifier = getIdentifier(identifier);
@@ -340,7 +321,7 @@ class RecordArrayManager {
340
321
  @method recordDidChange
341
322
  @internal
342
323
  */
343
- recordDidChange(identifier: StableRecordIdentifier): void {
324
+ recordDidChange(identifier) {
344
325
  if (this.isDestroying || this.isDestroyed) {
345
326
  return;
346
327
  }
@@ -359,26 +340,22 @@ class RecordArrayManager {
359
340
  return;
360
341
  }
361
342
 
362
- // TODO do we still need this schedule?
363
- // eslint-disable-next-line @typescript-eslint/unbound-method
364
343
  emberBackburner.schedule('actions', this, this._flush);
365
344
  }
366
345
 
367
346
  willDestroy() {
368
- Object.keys(this._liveRecordArrays).forEach((modelName) => this._liveRecordArrays[modelName]!.destroy());
347
+ Object.keys(this._liveRecordArrays).forEach((modelName) => this._liveRecordArrays[modelName].destroy());
369
348
  this._adapterPopulatedRecordArrays.forEach((entry) => entry.destroy());
370
349
  this.isDestroyed = true;
371
350
  }
372
351
 
373
352
  destroy() {
374
353
  this.isDestroying = true;
375
- // TODO do we still need this schedule?
376
- // eslint-disable-next-line @typescript-eslint/unbound-method
377
354
  emberBackburner.schedule('actions', this, this.willDestroy);
378
355
  }
379
356
  }
380
357
 
381
- function removeFromArray(array: RecordArray[], item: RecordArray): boolean {
358
+ function removeFromArray(array, item) {
382
359
  let index = array.indexOf(item);
383
360
 
384
361
  if (index !== -1) {
@@ -389,13 +366,9 @@ function removeFromArray(array: RecordArray[], item: RecordArray): boolean {
389
366
  return false;
390
367
  }
391
368
 
392
- function updateLiveRecordArray(
393
- store: CoreStore,
394
- recordArray: RecordArray,
395
- identifiers: StableRecordIdentifier[]
396
- ): void {
397
- let identifiersToAdd: StableRecordIdentifier[] = [];
398
- let identifiersToRemove: StableRecordIdentifier[] = [];
369
+ function updateLiveRecordArray(store, recordArray, identifiers) {
370
+ let identifiersToAdd = [];
371
+ let identifiersToRemove = [];
399
372
 
400
373
  for (let i = 0; i < identifiers.length; i++) {
401
374
  let identifier = identifiers[i];
@@ -423,13 +396,13 @@ function updateLiveRecordArray(
423
396
  }
424
397
  }
425
398
 
426
- function removeFromAdapterPopulatedRecordArrays(store: CoreStore, identifiers: StableRecordIdentifier[]): void {
399
+ function removeFromAdapterPopulatedRecordArrays(store, identifiers) {
427
400
  for (let i = 0; i < identifiers.length; i++) {
428
401
  removeFromAll(store, identifiers[i]);
429
402
  }
430
403
  }
431
404
 
432
- function removeFromAll(store: CoreStore, identifier: StableRecordIdentifier): void {
405
+ function removeFromAll(store, identifier) {
433
406
  identifier = getIdentifier(identifier);
434
407
  const recordArrays = recordArraysForIdentifier(identifier);
435
408
 
@@ -0,0 +1,95 @@
1
+ import { A } from '@ember/array';
2
+ import { get } from '@ember/object';
3
+
4
+ import RecordArray from './record-array';
5
+
6
+ /**
7
+ @module @ember-data/store
8
+ */
9
+
10
+ /**
11
+ Represents an ordered list of records whose order and membership is
12
+ determined by the adapter. For example, a query sent to the adapter
13
+ may trigger a search on the server, whose results would be loaded
14
+ into an instance of the `AdapterPopulatedRecordArray`.
15
+
16
+ This class should not be imported and instantiated by consuming applications.
17
+
18
+ ---
19
+
20
+ If you want to update the array and get the latest records from the
21
+ adapter, you can invoke [`update()`](AdapterPopulatedRecordArray/methods/update?anchor=update):
22
+
23
+ Example
24
+
25
+ ```javascript
26
+ // GET /users?isAdmin=true
27
+ store.query('user', { isAdmin: true }).then(function(admins) {
28
+
29
+ admins.then(function() {
30
+ console.log(admins.get("length")); // 42
31
+ });
32
+
33
+ // somewhere later in the app code, when new admins have been created
34
+ // in the meantime
35
+ //
36
+ // GET /users?isAdmin=true
37
+ admins.update().then(function() {
38
+ admins.get('isUpdating'); // false
39
+ console.log(admins.get("length")); // 123
40
+ });
41
+
42
+ admins.get('isUpdating'); // true
43
+ }
44
+ ```
45
+
46
+ @class AdapterPopulatedRecordArray
47
+ @public
48
+ @extends RecordArray
49
+ */
50
+ export default RecordArray.extend({
51
+ init() {
52
+ this.set('content', this.get('content') || A());
53
+
54
+ this._super(...arguments);
55
+ this.query = this.query || null;
56
+ this.links = this.links || null;
57
+ },
58
+
59
+ replace() {
60
+ throw new Error(`The result of a server query (on ${this.modelName}) is immutable.`);
61
+ },
62
+
63
+ _update() {
64
+ let store = get(this, 'store');
65
+ let query = get(this, 'query');
66
+
67
+ return store._query(this.modelName, query, this);
68
+ },
69
+
70
+ _setObjects(identifiersOrInternalModels, payload) {
71
+ // TODO: initial load should not cause change events at all, only
72
+ // subsequent. This requires changing the public api of adapter.query, but
73
+ // hopefully we can do that soon.
74
+ this.get('content').setObjects(identifiersOrInternalModels);
75
+
76
+ this.setProperties({
77
+ isLoaded: true,
78
+ isUpdating: false,
79
+ meta: { ...payload.meta },
80
+ links: { ...payload.links },
81
+ });
82
+
83
+ this.manager._associateWithRecordArray(identifiersOrInternalModels, this);
84
+ },
85
+
86
+ /**
87
+ @method _setIdentifiers
88
+ @param {StableRecordIdentifier[]} identifiers
89
+ @param {Object} payload normalized payload
90
+ @private
91
+ */
92
+ _setIdentifiers(identifiers, payload) {
93
+ this._setObjects(identifiers, payload);
94
+ },
95
+ });