@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.
@@ -3,7 +3,6 @@
3
3
  */
4
4
  import { assert } from '@ember/debug';
5
5
 
6
- import { REQUEST_SERVICE } from '@ember-data/canary-features';
7
6
  /*
8
7
  This file encapsulates the various states that a record can transition
9
8
  through during its lifecycle.
@@ -431,6 +430,8 @@ createdState.uncommitted.rollback = function (internalModel) {
431
430
  };
432
431
 
433
432
  createdState.uncommitted.pushedData = function (internalModel) {
433
+ // TODO @runspired consider where to do this once we kill off state machine
434
+ internalModel.store._notificationManager.notify(internalModel.identifier, 'identity');
434
435
  internalModel.transitionTo('loaded.updated.uncommitted');
435
436
  internalModel.triggerLater('didLoad');
436
437
  };
@@ -494,9 +495,6 @@ const RootState = {
494
495
 
495
496
  // EVENTS
496
497
  loadingData(internalModel, promise) {
497
- if (!REQUEST_SERVICE) {
498
- internalModel._promiseProxy = promise;
499
- }
500
498
  internalModel.transitionTo('loading');
501
499
  },
502
500
 
@@ -587,11 +585,7 @@ const RootState = {
587
585
  internalModel.transitionTo('updated.inFlight');
588
586
  },
589
587
 
590
- reloadRecord(internalModel, { resolve, options }) {
591
- if (!REQUEST_SERVICE) {
592
- resolve(internalModel.store._reloadRecord(internalModel, options));
593
- }
594
- },
588
+ reloadRecord() {},
595
589
 
596
590
  deleteRecord(internalModel) {
597
591
  internalModel.transitionTo('deleted.uncommitted');
@@ -5,11 +5,8 @@
5
5
  import { A } from '@ember/array';
6
6
  import { assert } from '@ember/debug';
7
7
  import { get, set } from '@ember/object';
8
- import { assign } from '@ember/polyfills';
9
8
  import { _backburner as emberBackburner } from '@ember/runloop';
10
9
 
11
- import { REMOVE_RECORD_ARRAY_MANAGER_LEGACY_COMPAT } from '@ember-data/canary-features';
12
-
13
10
  import isStableIdentifier from '../identifiers/is-stable-identifier';
14
11
  import { AdapterPopulatedRecordArray, RecordArray } from './record-arrays';
15
12
  import { internalModelFactoryFor } from './store/internal-model-factory';
@@ -28,11 +25,10 @@ export function recordArraysForIdentifier(identifierOrInternalModel) {
28
25
  }
29
26
 
30
27
  const pendingForIdentifier = new Set([]);
31
- const IMDematerializing = new WeakMap();
32
28
 
33
29
  const getIdentifier = function getIdentifier(identifierOrInternalModel) {
34
30
  let i = identifierOrInternalModel;
35
- if (!REMOVE_RECORD_ARRAY_MANAGER_LEGACY_COMPAT && !isStableIdentifier(identifierOrInternalModel)) {
31
+ if (!isStableIdentifier(identifierOrInternalModel)) {
36
32
  // identifier may actually be an internalModel
37
33
  // but during materialization we will get an identifier that
38
34
  // has already been removed from the identifiers cache yet
@@ -43,18 +39,7 @@ const getIdentifier = function getIdentifier(identifierOrInternalModel) {
43
39
  return i;
44
40
  };
45
41
 
46
- // REMOVE_RECORD_ARRAY_MANAGER_LEGACY_COMPAT only
47
42
  const peekIMCache = function peekIMCache(cache, identifier) {
48
- if (!REMOVE_RECORD_ARRAY_MANAGER_LEGACY_COMPAT) {
49
- let im = IMDematerializing.get(identifier);
50
- if (im === undefined) {
51
- // if not im._isDematerializing
52
- im = cache.peek(identifier);
53
- }
54
-
55
- return im;
56
- }
57
-
58
43
  return cache.peek(identifier);
59
44
  };
60
45
 
@@ -281,8 +266,8 @@ class RecordArrayManager {
281
266
  manager: this,
282
267
  isLoaded: true,
283
268
  isUpdating: false,
284
- meta: assign({}, payload.meta),
285
- links: assign({}, payload.links),
269
+ meta: { ...payload.meta },
270
+ links: { ...payload.links },
286
271
  });
287
272
 
288
273
  this._associateWithRecordArray(identifiers, array);
@@ -352,14 +337,6 @@ class RecordArrayManager {
352
337
  let modelName = identifier.type;
353
338
  identifier = getIdentifier(identifier);
354
339
 
355
- if (!REMOVE_RECORD_ARRAY_MANAGER_LEGACY_COMPAT) {
356
- const cache = internalModelFactoryFor(this.store);
357
- const im = peekIMCache(cache, identifier);
358
- if (im && im._isDematerializing) {
359
- IMDematerializing.set(identifier, im);
360
- }
361
- }
362
-
363
340
  if (pendingForIdentifier.has(identifier)) {
364
341
  return;
365
342
  }
@@ -429,15 +406,10 @@ const updateLiveRecordArray = function updateLiveRecordArray(store, recordArray,
429
406
  };
430
407
 
431
408
  const pushIdentifiers = function pushIdentifiers(recordArray, identifiers, cache) {
432
- if (!REMOVE_RECORD_ARRAY_MANAGER_LEGACY_COMPAT && !recordArray._pushIdentifiers) {
433
- // deprecate('not allowed to use this intimate api any more');
434
- recordArray._pushInternalModels(identifiers.map((i) => peekIMCache(cache, i)));
435
- } else {
436
- recordArray._pushIdentifiers(identifiers);
437
- }
409
+ recordArray._pushIdentifiers(identifiers);
438
410
  };
439
411
  const removeIdentifiers = function removeIdentifiers(recordArray, identifiers, cache) {
440
- if (!REMOVE_RECORD_ARRAY_MANAGER_LEGACY_COMPAT && !recordArray._removeIdentifiers) {
412
+ if (!recordArray._removeIdentifiers) {
441
413
  // deprecate('not allowed to use this intimate api any more');
442
414
  recordArray._removeInternalModels(identifiers.map((i) => peekIMCache(cache, i)));
443
415
  } else {
@@ -1,6 +1,5 @@
1
1
  import { A } from '@ember/array';
2
2
  import { get } from '@ember/object';
3
- import { assign } from '@ember/polyfills';
4
3
  import { once } from '@ember/runloop';
5
4
  import { DEBUG } from '@glimmer/env';
6
5
 
@@ -86,8 +85,8 @@ let AdapterPopulatedRecordArray = RecordArray.extend({
86
85
  this.setProperties({
87
86
  isLoaded: true,
88
87
  isUpdating: false,
89
- meta: assign({}, payload.meta),
90
- links: assign({}, payload.links),
88
+ meta: { ...payload.meta },
89
+ links: { ...payload.links },
91
90
  });
92
91
 
93
92
  this.manager._associateWithRecordArray(identifiersOrInternalModels, this);
@@ -4,7 +4,7 @@ import type CoreStore from './core-store';
4
4
 
5
5
  type UnsubscribeToken = Object;
6
6
 
7
- const Cache = new WeakMap<StableRecordIdentifier, NotificationCallback>();
7
+ const Cache = new WeakMap<StableRecordIdentifier, Map<UnsubscribeToken, NotificationCallback>>();
8
8
  const Tokens = new WeakMap<UnsubscribeToken, StableRecordIdentifier>();
9
9
 
10
10
  export type NotificationType =
@@ -29,7 +29,8 @@ export function unsubscribe(token: UnsubscribeToken) {
29
29
  throw new Error('Passed unknown unsubscribe token to unsubscribe');
30
30
  }
31
31
  Tokens.delete(token);
32
- Cache.delete(identifier);
32
+ const map = Cache.get(identifier);
33
+ map?.delete(token);
33
34
  }
34
35
  /*
35
36
  Currently only support a single callback per identifier
@@ -39,8 +40,13 @@ export default class NotificationManager {
39
40
 
40
41
  subscribe(identifier: RecordIdentifier, callback: NotificationCallback): UnsubscribeToken {
41
42
  let stableIdentifier = identifierCacheFor(this.store).getOrCreateRecordIdentifier(identifier);
42
- Cache.set(stableIdentifier, callback);
43
+ let map = Cache.get(stableIdentifier);
44
+ if (map === undefined) {
45
+ map = new Map();
46
+ Cache.set(stableIdentifier, map);
47
+ }
43
48
  let unsubToken = {};
49
+ map.set(unsubToken, callback);
44
50
  Tokens.set(unsubToken, stableIdentifier);
45
51
  return unsubToken;
46
52
  }
@@ -49,11 +55,13 @@ export default class NotificationManager {
49
55
  notify(identifier: RecordIdentifier, value: 'errors' | 'meta' | 'identity' | 'unload' | 'state'): boolean;
50
56
  notify(identifier: RecordIdentifier, value: NotificationType, key?: string): boolean {
51
57
  let stableIdentifier = identifierCacheFor(this.store).getOrCreateRecordIdentifier(identifier);
52
- let callback = Cache.get(stableIdentifier);
53
- if (!callback) {
58
+ let callbackMap = Cache.get(stableIdentifier);
59
+ if (!callbackMap || !callbackMap.size) {
54
60
  return false;
55
61
  }
56
- callback(stableIdentifier, value, key);
62
+ callbackMap.forEach((cb) => {
63
+ cb(stableIdentifier, value, key);
64
+ });
57
65
  return true;
58
66
  }
59
67
  }
@@ -1,11 +1,19 @@
1
1
  import { deprecate } from '@ember/debug';
2
+ import { dependentKeyCompat } from '@ember/object/compat';
3
+ import { cached, tracked } from '@glimmer/tracking';
2
4
 
3
5
  import { resolve } from 'rsvp';
4
6
 
5
7
  import { DEPRECATE_BELONGS_TO_REFERENCE_PUSH } from '@ember-data/private-build-infra/deprecations';
8
+ import type { BelongsToRelationship } from '@ember-data/record-data/-private';
6
9
  import { assertPolymorphicType } from '@ember-data/store/-debug';
7
10
 
11
+ import { SingleResourceDocument } from '../../ts-interfaces/ember-data-json-api';
12
+ import { StableRecordIdentifier } from '../../ts-interfaces/identifier';
13
+ import CoreStore from '../core-store';
14
+ import { NotificationType, unsubscribe } from '../record-notification-manager';
8
15
  import { internalModelFactoryFor, peekRecordIdentifier, recordIdentifierFor } from '../store/internal-model-factory';
16
+ import RecordReference from './record';
9
17
  import Reference from './reference';
10
18
 
11
19
  /**
@@ -22,17 +30,77 @@ import Reference from './reference';
22
30
  @extends Reference
23
31
  */
24
32
  export default class BelongsToReference extends Reference {
25
- constructor(store, parentIMOrIdentifier, belongsToRelationship, key) {
26
- super(store, parentIMOrIdentifier);
33
+ declare key: string;
34
+ declare belongsToRelationship: BelongsToRelationship;
35
+ declare type: string;
36
+ declare parent: RecordReference;
37
+ declare parentIdentifier: StableRecordIdentifier;
38
+
39
+ // unsubscribe tokens given to us by the notification manager
40
+ #token!: Object;
41
+ #relatedToken: Object | null = null;
42
+
43
+ @tracked _ref = 0;
44
+
45
+ constructor(
46
+ store: CoreStore,
47
+ parentIdentifier: StableRecordIdentifier,
48
+ belongsToRelationship: BelongsToRelationship,
49
+ key: string
50
+ ) {
51
+ super(store, parentIdentifier);
27
52
  this.key = key;
28
53
  this.belongsToRelationship = belongsToRelationship;
29
54
  this.type = belongsToRelationship.definition.type;
30
- this.parent = internalModelFactoryFor(store).peek(parentIMOrIdentifier).recordReference;
31
- this.parentIdentifier = parentIMOrIdentifier;
55
+ const parent = internalModelFactoryFor(store).peek(parentIdentifier);
56
+ this.parent = parent!.recordReference;
57
+ this.parentIdentifier = parentIdentifier;
58
+
59
+ this.#token = store._notificationManager.subscribe(
60
+ parentIdentifier,
61
+ (_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
62
+ if ((bucket === 'relationships' || bucket === 'property') && notifiedKey === key) {
63
+ this._ref++;
64
+ }
65
+ }
66
+ );
32
67
 
33
68
  // TODO inverse
34
69
  }
35
70
 
71
+ destroy() {
72
+ unsubscribe(this.#token);
73
+ if (this.#relatedToken) {
74
+ unsubscribe(this.#relatedToken);
75
+ }
76
+ }
77
+
78
+ @cached
79
+ @dependentKeyCompat
80
+ get _relatedIdentifier(): StableRecordIdentifier | null {
81
+ this._ref; // consume the tracked prop
82
+ if (this.#relatedToken) {
83
+ unsubscribe(this.#relatedToken);
84
+ }
85
+
86
+ let resource = this._resource();
87
+ if (resource && resource.data) {
88
+ const identifier = this.store.identifierCache.getOrCreateRecordIdentifier(resource.data);
89
+ this.#relatedToken = this.store._notificationManager.subscribe(
90
+ identifier,
91
+ (_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
92
+ if (bucket === 'identity' || ((bucket === 'attributes' || bucket === 'property') && notifiedKey === 'id')) {
93
+ this._ref++;
94
+ }
95
+ }
96
+ );
97
+
98
+ return identifier;
99
+ }
100
+
101
+ return null;
102
+ }
103
+
36
104
  /**
37
105
  The `id` of the record that this reference refers to. Together, the
38
106
  `type()` and `id()` methods form a composite key for the identity
@@ -73,13 +141,8 @@ export default class BelongsToReference extends Reference {
73
141
  @public
74
142
  @return {String} The id of the record in this belongsTo relationship.
75
143
  */
76
- id() {
77
- let id = null;
78
- let resource = this._resource();
79
- if (resource && resource.data) {
80
- id = resource.data.id;
81
- }
82
- return id;
144
+ id(): string | null {
145
+ return this._relatedIdentifier?.id || null;
83
146
  }
84
147
 
85
148
  _resource() {
@@ -132,10 +195,10 @@ export default class BelongsToReference extends Reference {
132
195
  @param {Object|Promise} objectOrPromise a promise that resolves to a JSONAPI document object describing the new value of this relationship.
133
196
  @return {Promise<record>} A promise that resolves with the new value in this belongs-to relationship.
134
197
  */
135
- push(objectOrPromise) {
198
+ async push(objectOrPromise: Object | SingleResourceDocument): Promise<Object> {
136
199
  // TODO deprecate thenable support
137
200
  return resolve(objectOrPromise).then((data) => {
138
- let record;
201
+ let record: Object;
139
202
 
140
203
  if (DEPRECATE_BELONGS_TO_REFERENCE_PUSH && peekRecordIdentifier(data)) {
141
204
  deprecate('Pushing a record into a BelongsToReference is deprecated', false, {
@@ -147,15 +210,16 @@ export default class BelongsToReference extends Reference {
147
210
  enabled: '3.16',
148
211
  },
149
212
  });
150
- record = data;
213
+ record = data as Object;
151
214
  } else {
152
- record = this.store.push(data);
215
+ record = this.store.push(data as SingleResourceDocument);
153
216
  }
154
217
 
218
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
155
219
  assertPolymorphicType(
156
220
  this.belongsToRelationship.identifier,
157
221
  this.belongsToRelationship.definition,
158
- record._internalModel.identifier,
222
+ recordIdentifierFor(record),
159
223
  this.store
160
224
  );
161
225
 
@@ -223,7 +287,7 @@ export default class BelongsToReference extends Reference {
223
287
  @public
224
288
  @return {Model} the record in this relationship
225
289
  */
226
- value() {
290
+ value(): Object | null {
227
291
  let resource = this._resource();
228
292
  if (resource && resource.data) {
229
293
  let inverseInternalModel = this.store._internalModelForResource(resource.data);
@@ -299,7 +363,7 @@ export default class BelongsToReference extends Reference {
299
363
  */
300
364
  load(options) {
301
365
  let parentInternalModel = internalModelFactoryFor(this.store).peek(this.parentIdentifier);
302
- return parentInternalModel.getBelongsTo(this.key, options);
366
+ return parentInternalModel!.getBelongsTo(this.key, options);
303
367
  }
304
368
 
305
369
  /**
@@ -354,7 +418,7 @@ export default class BelongsToReference extends Reference {
354
418
  */
355
419
  reload(options) {
356
420
  let parentInternalModel = internalModelFactoryFor(this.store).peek(this.parentIdentifier);
357
- return parentInternalModel.reloadBelongsTo(this.key, options).then((internalModel) => {
421
+ return parentInternalModel!.reloadBelongsTo(this.key, options).then((internalModel) => {
358
422
  return this.value();
359
423
  });
360
424
  }
@@ -1,10 +1,22 @@
1
+ import { dependentKeyCompat } from '@ember/object/compat';
1
2
  import { DEBUG } from '@glimmer/env';
3
+ import { cached, tracked } from '@glimmer/tracking';
2
4
 
3
5
  import { resolve } from 'rsvp';
4
6
 
7
+ import type { ManyRelationship } from '@ember-data/record-data/-private';
5
8
  import { assertPolymorphicType } from '@ember-data/store/-debug';
6
9
 
10
+ import {
11
+ CollectionResourceDocument,
12
+ ExistingResourceObject,
13
+ SingleResourceDocument,
14
+ } from '../../ts-interfaces/ember-data-json-api';
15
+ import { StableRecordIdentifier } from '../../ts-interfaces/identifier';
16
+ import CoreStore from '../core-store';
17
+ import { NotificationType, unsubscribe } from '../record-notification-manager';
7
18
  import { internalModelFactoryFor, recordIdentifierFor } from '../store/internal-model-factory';
19
+ import RecordReference from './record';
8
20
  import Reference, { internalModelForReference } from './reference';
9
21
 
10
22
  /**
@@ -20,17 +32,84 @@ import Reference, { internalModelForReference } from './reference';
20
32
  @extends Reference
21
33
  */
22
34
  export default class HasManyReference extends Reference {
23
- constructor(store, parentIMOrIdentifier, hasManyRelationship, key) {
24
- super(store, parentIMOrIdentifier);
35
+ declare key: string;
36
+ declare hasManyRelationship: ManyRelationship;
37
+ declare type: string;
38
+ declare parent: RecordReference;
39
+ declare parentIdentifier: StableRecordIdentifier;
40
+
41
+ // unsubscribe tokens given to us by the notification manager
42
+ #token!: Object;
43
+ #relatedTokenMap!: Map<StableRecordIdentifier, Object>;
44
+
45
+ @tracked _ref = 0;
46
+
47
+ constructor(
48
+ store: CoreStore,
49
+ parentIdentifier: StableRecordIdentifier,
50
+ hasManyRelationship: ManyRelationship,
51
+ key: string
52
+ ) {
53
+ super(store, parentIdentifier);
25
54
  this.key = key;
26
55
  this.hasManyRelationship = hasManyRelationship;
27
56
  this.type = hasManyRelationship.definition.type;
28
57
 
29
- this.parent = internalModelFactoryFor(store).peek(parentIMOrIdentifier).recordReference;
58
+ this.parent = internalModelFactoryFor(store).peek(parentIdentifier)!.recordReference;
30
59
 
60
+ this.#token = store._notificationManager.subscribe(
61
+ parentIdentifier,
62
+ (_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
63
+ if ((bucket === 'relationships' || bucket === 'property') && notifiedKey === key) {
64
+ this._ref++;
65
+ }
66
+ }
67
+ );
68
+ this.#relatedTokenMap = new Map();
31
69
  // TODO inverse
32
70
  }
33
71
 
72
+ destroy() {
73
+ unsubscribe(this.#token);
74
+ this.#relatedTokenMap.forEach((token) => {
75
+ unsubscribe(token);
76
+ });
77
+ this.#relatedTokenMap.clear();
78
+ }
79
+
80
+ @cached
81
+ @dependentKeyCompat
82
+ get _relatedIdentifiers(): StableRecordIdentifier[] {
83
+ this._ref; // consume the tracked prop
84
+
85
+ let resource = this._resource();
86
+
87
+ this.#relatedTokenMap.forEach((token) => {
88
+ unsubscribe(token);
89
+ });
90
+ this.#relatedTokenMap.clear();
91
+
92
+ if (resource && resource.data) {
93
+ return resource.data.map((resourceIdentifier) => {
94
+ const identifier = this.store.identifierCache.getOrCreateRecordIdentifier(resourceIdentifier);
95
+ const token = this.store._notificationManager.subscribe(
96
+ identifier,
97
+ (_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
98
+ if (bucket === 'identity' || ((bucket === 'attributes' || bucket === 'property') && notifiedKey === 'id')) {
99
+ this._ref++;
100
+ }
101
+ }
102
+ );
103
+
104
+ this.#relatedTokenMap.set(identifier, token);
105
+
106
+ return identifier;
107
+ });
108
+ }
109
+
110
+ return [];
111
+ }
112
+
34
113
  _resource() {
35
114
  return this.recordData.getHasMany(this.key);
36
115
  }
@@ -77,7 +156,7 @@ export default class HasManyReference extends Reference {
77
156
  @public
78
157
  @return {String} The name of the remote type. This should either be `link` or `ids`
79
158
  */
80
- remoteType() {
159
+ remoteType(): 'link' | 'ids' {
81
160
  let value = this._resource();
82
161
  if (value && value.links && value.links.related) {
83
162
  return 'link';
@@ -121,15 +200,8 @@ export default class HasManyReference extends Reference {
121
200
  @public
122
201
  @return {Array} The ids in this has-many relationship
123
202
  */
124
- ids() {
125
- let resource = this._resource();
126
-
127
- let ids = [];
128
- if (resource.data) {
129
- ids = resource.data.map((data) => data.id);
130
- }
131
-
132
- return ids;
203
+ ids(): Array<string | null> {
204
+ return this._relatedIdentifiers.map((identifier) => identifier.id);
133
205
  }
134
206
 
135
207
  /**
@@ -177,45 +249,50 @@ export default class HasManyReference extends Reference {
177
249
  @param {Array|Promise} objectOrPromise a promise that resolves to a JSONAPI document object describing the new value of this relationship.
178
250
  @return {ManyArray}
179
251
  */
180
- push(objectOrPromise) {
181
- return resolve(objectOrPromise).then((payload) => {
182
- let array = payload;
183
-
184
- if (typeof payload === 'object' && payload.data) {
185
- array = payload.data;
186
- }
252
+ async push(
253
+ objectOrPromise: ExistingResourceObject[] | CollectionResourceDocument | { data: SingleResourceDocument[] }
254
+ ): Promise<any> {
255
+ const payload = await resolve(objectOrPromise);
256
+ let array: Array<ExistingResourceObject | SingleResourceDocument>;
257
+
258
+ if (!Array.isArray(payload) && typeof payload === 'object' && Array.isArray(payload.data)) {
259
+ array = payload.data;
260
+ } else {
261
+ array = payload as ExistingResourceObject[];
262
+ }
187
263
 
188
- let internalModel = internalModelForReference(this);
264
+ const internalModel = internalModelForReference(this)!;
265
+ const { store } = this;
189
266
 
190
- let identifiers = array.map((obj) => {
191
- let record = this.store.push(obj);
267
+ let identifiers = array.map((obj) => {
268
+ let record;
269
+ if ('data' in obj) {
270
+ // TODO deprecate pushing non-valid JSON:API here
271
+ record = store.push(obj);
272
+ } else {
273
+ record = store.push({ data: obj });
274
+ }
192
275
 
193
- if (DEBUG) {
194
- let relationshipMeta = this.hasManyRelationship.definition;
195
- assertPolymorphicType(
196
- internalModel.identifier,
197
- relationshipMeta,
198
- record._internalModel.identifier,
199
- this.store
200
- );
201
- }
202
- return recordIdentifierFor(record);
203
- });
276
+ if (DEBUG) {
277
+ let relationshipMeta = this.hasManyRelationship.definition;
278
+ let identifier = this.hasManyRelationship.identifier;
279
+ assertPolymorphicType(identifier, relationshipMeta, recordIdentifierFor(record), store);
280
+ }
281
+ return recordIdentifierFor(record);
282
+ });
204
283
 
205
- const { graph, identifier } = this.hasManyRelationship;
206
- this.store._backburner.join(() => {
207
- graph.push({
208
- op: 'replaceRelatedRecords',
209
- record: identifier,
210
- field: this.key,
211
- value: identifiers,
212
- });
284
+ const { graph, identifier } = this.hasManyRelationship;
285
+ store._backburner.join(() => {
286
+ graph.push({
287
+ op: 'replaceRelatedRecords',
288
+ record: identifier,
289
+ field: this.key,
290
+ value: identifiers,
213
291
  });
214
-
215
- return internalModel.getHasMany(this.key);
216
- // TODO IGOR it seems wrong that we were returning the many array here
217
- //return this.hasManyRelationship.manyArray;
218
292
  });
293
+
294
+ // TODO IGOR it seems wrong that we were returning the many array here
295
+ return internalModel.getHasMany(this.key);
219
296
  }
220
297
 
221
298
  _isLoaded() {
@@ -275,7 +352,7 @@ export default class HasManyReference extends Reference {
275
352
  @return {ManyArray}
276
353
  */
277
354
  value() {
278
- let internalModel = internalModelForReference(this);
355
+ let internalModel = internalModelForReference(this)!;
279
356
  if (this._isLoaded()) {
280
357
  return internalModel.getManyArray(this.key);
281
358
  }
@@ -348,7 +425,7 @@ export default class HasManyReference extends Reference {
348
425
  this has-many relationship.
349
426
  */
350
427
  load(options) {
351
- let internalModel = internalModelForReference(this);
428
+ let internalModel = internalModelForReference(this)!;
352
429
  return internalModel.getHasMany(this.key, options);
353
430
  }
354
431
 
@@ -403,7 +480,7 @@ export default class HasManyReference extends Reference {
403
480
  @return {Promise} a promise that resolves with the ManyArray in this has-many relationship.
404
481
  */
405
482
  reload(options) {
406
- let internalModel = internalModelForReference(this);
483
+ let internalModel = internalModelForReference(this)!;
407
484
  return internalModel.reloadHasMany(this.key, options);
408
485
  }
409
486
  }