@ember-data/model 4.7.0-beta.1 → 4.7.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.
@@ -1,15 +1,17 @@
1
+ import { deprecate } from '@ember/debug';
1
2
  import { dependentKeyCompat } from '@ember/object/compat';
2
3
  import { cached, tracked } from '@glimmer/tracking';
3
4
 
4
5
  import type { Object as JSONObject, Value as JSONValue } from 'json-typescript';
5
6
  import { resolve } from 'rsvp';
6
7
 
7
- import type { BelongsToRelationship } from '@ember-data/record-data/-private';
8
+ import { DEPRECATE_PROMISE_PROXIES } from '@ember-data/private-build-infra/deprecations';
9
+ import type { Graph } from '@ember-data/record-data/-private/graph/graph';
10
+ import type BelongsToRelationship from '@ember-data/record-data/-private/relationships/state/belongs-to';
8
11
  import type Store from '@ember-data/store';
9
12
  import { assertPolymorphicType } from '@ember-data/store/-debug';
10
13
  import { recordIdentifierFor } from '@ember-data/store/-private';
11
- import type { NotificationType } from '@ember-data/store/-private/record-notification-manager';
12
- import type { DebugWeakCache } from '@ember-data/store/-private/weak-cache';
14
+ import type { NotificationType } from '@ember-data/store/-private/managers/record-notification-manager';
13
15
  import type {
14
16
  LinkObject,
15
17
  Links,
@@ -52,31 +54,34 @@ export default class BelongsToReference {
52
54
  declare key: string;
53
55
  declare belongsToRelationship: BelongsToRelationship;
54
56
  declare type: string;
55
- #identifier: StableRecordIdentifier;
57
+ ___identifier: StableRecordIdentifier;
56
58
  declare store: Store;
59
+ declare graph: Graph;
57
60
 
58
61
  // unsubscribe tokens given to us by the notification manager
59
- #token!: Object;
60
- #relatedToken: Object | null = null;
62
+ ___token!: object;
63
+ ___relatedToken: object | null = null;
61
64
 
62
65
  @tracked _ref = 0;
63
66
 
64
67
  constructor(
65
68
  store: Store,
69
+ graph: Graph,
66
70
  parentIdentifier: StableRecordIdentifier,
67
71
  belongsToRelationship: BelongsToRelationship,
68
72
  key: string
69
73
  ) {
74
+ this.graph = graph;
70
75
  this.key = key;
71
76
  this.belongsToRelationship = belongsToRelationship;
72
77
  this.type = belongsToRelationship.definition.type;
73
78
  this.store = store;
74
- this.#identifier = parentIdentifier;
79
+ this.___identifier = parentIdentifier;
75
80
 
76
- this.#token = store._notificationManager.subscribe(
81
+ this.___token = store._notificationManager.subscribe(
77
82
  parentIdentifier,
78
83
  (_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
79
- if ((bucket === 'relationships' || bucket === 'property') && notifiedKey === key) {
84
+ if (bucket === 'relationships' && notifiedKey === key) {
80
85
  this._ref++;
81
86
  }
82
87
  }
@@ -88,9 +93,11 @@ export default class BelongsToReference {
88
93
  destroy() {
89
94
  // TODO @feature we need the notification manager often enough
90
95
  // we should potentially just expose it fully public
91
- this.store._notificationManager.unsubscribe(this.#token);
92
- if (this.#relatedToken) {
93
- this.store._notificationManager.unsubscribe(this.#relatedToken);
96
+ this.store._notificationManager.unsubscribe(this.___token);
97
+ this.___token = null as unknown as object;
98
+ if (this.___relatedToken) {
99
+ this.store._notificationManager.unsubscribe(this.___relatedToken);
100
+ this.___relatedToken = null;
94
101
  }
95
102
  }
96
103
 
@@ -98,17 +105,18 @@ export default class BelongsToReference {
98
105
  @dependentKeyCompat
99
106
  get _relatedIdentifier(): StableRecordIdentifier | null {
100
107
  this._ref; // consume the tracked prop
101
- if (this.#relatedToken) {
102
- this.store._notificationManager.unsubscribe(this.#relatedToken);
108
+ if (this.___relatedToken) {
109
+ this.store._notificationManager.unsubscribe(this.___relatedToken);
110
+ this.___relatedToken = null;
103
111
  }
104
112
 
105
113
  let resource = this._resource();
106
114
  if (resource && resource.data) {
107
115
  const identifier = this.store.identifierCache.getOrCreateRecordIdentifier(resource.data);
108
- this.#relatedToken = this.store._notificationManager.subscribe(
116
+ this.___relatedToken = this.store._notificationManager.subscribe(
109
117
  identifier,
110
118
  (_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
111
- if (bucket === 'identity' || ((bucket === 'attributes' || bucket === 'property') && notifiedKey === 'id')) {
119
+ if (bucket === 'identity' || (bucket === 'attributes' && notifiedKey === 'id')) {
112
120
  this._ref++;
113
121
  }
114
122
  }
@@ -125,7 +133,7 @@ export default class BelongsToReference {
125
133
  `type()` and `id()` methods form a composite key for the identity
126
134
  map. This can be used to access the id of an async relationship
127
135
  without triggering a fetch that would normally happen if you
128
- attempted to use `record.get('relationship.id')`.
136
+ attempted to use `record.relationship.id`.
129
137
 
130
138
  Example
131
139
 
@@ -134,7 +142,7 @@ export default class BelongsToReference {
134
142
  import Model, { belongsTo } from '@ember-data/model';
135
143
 
136
144
  export default class BlogModel extends Model {
137
- @belongsTo({ async: true }) user;
145
+ @belongsTo('user', { async: true, inverse: null }) user;
138
146
  }
139
147
 
140
148
  let blog = store.push({
@@ -174,7 +182,7 @@ export default class BelongsToReference {
174
182
  // models/blog.js
175
183
  import Model, { belongsTo } from '@ember-data/model';
176
184
  export default Model.extend({
177
- user: belongsTo({ async: true })
185
+ user: belongsTo('user', { async: true, inverse: null })
178
186
  });
179
187
 
180
188
  let blog = store.push({
@@ -236,7 +244,7 @@ export default class BelongsToReference {
236
244
  // models/blog.js
237
245
  import Model, { belongsTo } from '@ember-data/model';
238
246
  export default Model.extend({
239
- user: belongsTo({ async: true })
247
+ user: belongsTo('user', { async: true, inverse: null })
240
248
  });
241
249
 
242
250
  let blog = store.push({
@@ -277,7 +285,9 @@ export default class BelongsToReference {
277
285
  }
278
286
 
279
287
  _resource() {
280
- return this.store._instanceCache.recordDataFor(this.#identifier, false).getBelongsTo(this.key);
288
+ return this.store._instanceCache
289
+ .getRecordData(this.___identifier)
290
+ .getRelationship(this.___identifier, this.key) as SingleResourceRelationship;
281
291
  }
282
292
 
283
293
  /**
@@ -291,7 +301,7 @@ export default class BelongsToReference {
291
301
  import Model, { hasMany } from '@ember-data/model';
292
302
 
293
303
  export default class PostModel extends Model {
294
- @hasMany({ async: true }) comments;
304
+ @hasMany('comment', { async: true, inverse: null }) comments;
295
305
  }
296
306
  ```
297
307
 
@@ -341,7 +351,7 @@ export default class BelongsToReference {
341
351
  import Model, { belongsTo } from '@ember-data/model';
342
352
 
343
353
  export default class BlogModel extends Model {
344
- @belongsTo({ async: true }) user;
354
+ @belongsTo('user', { async: true, inverse: null }) user;
345
355
  }
346
356
 
347
357
  let blog = store.push({
@@ -377,8 +387,25 @@ export default class BelongsToReference {
377
387
  @return {Promise<record>} A promise that resolves with the new value in this belongs-to relationship.
378
388
  */
379
389
  async push(data: SingleResourceDocument | Promise<SingleResourceDocument>): Promise<RecordInstance> {
380
- // TODO @deprecate pushing unresolved payloads
381
- const jsonApiDoc = await resolve(data);
390
+ let jsonApiDoc: SingleResourceDocument = data as SingleResourceDocument;
391
+ if (DEPRECATE_PROMISE_PROXIES && (data as { then: unknown }).then) {
392
+ jsonApiDoc = await resolve(data);
393
+ if (jsonApiDoc !== data) {
394
+ deprecate(
395
+ `You passed in a Promise to a Reference API that now expects a resolved value. await the value before setting it.`,
396
+ false,
397
+ {
398
+ id: 'ember-data:deprecate-promise-proxies',
399
+ until: '5.0',
400
+ since: {
401
+ enabled: '4.8',
402
+ available: '4.8',
403
+ },
404
+ for: 'ember-data',
405
+ }
406
+ );
407
+ }
408
+ }
382
409
  let record = this.store.push(jsonApiDoc);
383
410
 
384
411
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call
@@ -389,9 +416,9 @@ export default class BelongsToReference {
389
416
  this.store
390
417
  );
391
418
 
392
- const { graph, identifier } = this.belongsToRelationship;
393
- this.store._backburner.join(() => {
394
- graph.push({
419
+ const { identifier } = this.belongsToRelationship;
420
+ this.store._join(() => {
421
+ this.graph.push({
395
422
  op: 'replaceRelatedRecord',
396
423
  record: identifier,
397
424
  field: this.key,
@@ -404,7 +431,7 @@ export default class BelongsToReference {
404
431
 
405
432
  /**
406
433
  `value()` synchronously returns the current value of the belongs-to
407
- relationship. Unlike `record.get('relationshipName')`, calling
434
+ relationship. Unlike `record.relationshipName`, calling
408
435
  `value()` on a reference does not trigger a fetch if the async
409
436
  relationship is not yet loaded. If the relationship is not loaded
410
437
  it will always return `null`.
@@ -416,7 +443,7 @@ export default class BelongsToReference {
416
443
  import Model, { belongsTo } from '@ember-data/model';
417
444
 
418
445
  export default class BlogModel extends Model {
419
- @belongsTo({ async: true }) user;
446
+ @belongsTo('user', { async: true, inverse: null }) user;
420
447
  }
421
448
 
422
449
  let blog = store.push({
@@ -469,7 +496,7 @@ export default class BelongsToReference {
469
496
  import Model, { belongsTo } from '@ember-data/model';
470
497
 
471
498
  export default class BlogModel extends Model {
472
- @belongsTo({ async: true }) user;
499
+ @belongsTo('user', { async: true, inverse: null }) user;
473
500
  }
474
501
 
475
502
  let blog = store.push({
@@ -520,9 +547,9 @@ export default class BelongsToReference {
520
547
  @return {Promise} a promise that resolves with the record in this belongs-to relationship.
521
548
  */
522
549
  load(options?: Dict<unknown>) {
523
- const support: LegacySupport = (
524
- LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
525
- ).getWithError(this.#identifier);
550
+ const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
551
+ this.___identifier
552
+ )!;
526
553
  return support.getBelongsTo(this.key, options);
527
554
  }
528
555
 
@@ -539,7 +566,7 @@ export default class BelongsToReference {
539
566
  import Model, { belongsTo } from '@ember-data/model';
540
567
 
541
568
  export default class BlogModel extends Model {
542
- @belongsTo({ async: true }) user;
569
+ @belongsTo('user', { async: true, inverse: null }) user;
543
570
  }
544
571
 
545
572
  let blog = store.push({
@@ -577,9 +604,9 @@ export default class BelongsToReference {
577
604
  @return {Promise} a promise that resolves with the record in this belongs-to relationship after the reload has completed.
578
605
  */
579
606
  reload(options?: Dict<unknown>) {
580
- const support: LegacySupport = (
581
- LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
582
- ).getWithError(this.#identifier);
607
+ const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
608
+ this.___identifier
609
+ )!;
583
610
  return support.reloadBelongsTo(this.key, options).then(() => this.value());
584
611
  }
585
612
  }
@@ -1,3 +1,4 @@
1
+ import { deprecate } from '@ember/debug';
1
2
  import { dependentKeyCompat } from '@ember/object/compat';
2
3
  import { DEBUG } from '@glimmer/env';
3
4
  import { cached, tracked } from '@glimmer/tracking';
@@ -7,12 +8,13 @@ import { resolve } from 'rsvp';
7
8
 
8
9
  import { ManyArray } from 'ember-data/-private';
9
10
 
10
- import type { ManyRelationship } from '@ember-data/record-data/-private';
11
+ import { DEPRECATE_PROMISE_PROXIES } from '@ember-data/private-build-infra/deprecations';
12
+ import type { Graph } from '@ember-data/record-data/-private/graph/graph';
13
+ import type ManyRelationship from '@ember-data/record-data/-private/relationships/state/has-many';
11
14
  import type Store from '@ember-data/store';
12
15
  import { recordIdentifierFor } from '@ember-data/store';
13
16
  import { assertPolymorphicType } from '@ember-data/store/-debug';
14
- import type { NotificationType } from '@ember-data/store/-private/record-notification-manager';
15
- import type { DebugWeakCache } from '@ember-data/store/-private/weak-cache';
17
+ import type { NotificationType } from '@ember-data/store/-private/managers/record-notification-manager';
16
18
  import type {
17
19
  CollectionResourceDocument,
18
20
  CollectionResourceRelationship,
@@ -53,48 +55,51 @@ function isResourceIdentiferWithRelatedLinks(
53
55
  @extends Reference
54
56
  */
55
57
  export default class HasManyReference {
58
+ declare graph: Graph;
56
59
  declare key: string;
57
60
  declare hasManyRelationship: ManyRelationship;
58
61
  declare type: string;
59
62
  declare store: Store;
60
63
 
61
64
  // unsubscribe tokens given to us by the notification manager
62
- #token!: Object;
63
- #identifier: StableRecordIdentifier;
64
- #relatedTokenMap!: Map<StableRecordIdentifier, Object>;
65
+ ___token!: Object;
66
+ ___identifier: StableRecordIdentifier;
67
+ ___relatedTokenMap!: Map<StableRecordIdentifier, Object>;
65
68
 
66
69
  @tracked _ref = 0;
67
70
 
68
71
  constructor(
69
72
  store: Store,
73
+ graph: Graph,
70
74
  parentIdentifier: StableRecordIdentifier,
71
75
  hasManyRelationship: ManyRelationship,
72
76
  key: string
73
77
  ) {
78
+ this.graph = graph;
74
79
  this.key = key;
75
80
  this.hasManyRelationship = hasManyRelationship;
76
81
  this.type = hasManyRelationship.definition.type;
77
82
 
78
83
  this.store = store;
79
- this.#identifier = parentIdentifier;
80
- this.#token = store._notificationManager.subscribe(
84
+ this.___identifier = parentIdentifier;
85
+ this.___token = store._notificationManager.subscribe(
81
86
  parentIdentifier,
82
87
  (_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
83
- if ((bucket === 'relationships' || bucket === 'property') && notifiedKey === key) {
88
+ if (bucket === 'relationships' && notifiedKey === key) {
84
89
  this._ref++;
85
90
  }
86
91
  }
87
92
  );
88
- this.#relatedTokenMap = new Map();
93
+ this.___relatedTokenMap = new Map();
89
94
  // TODO inverse
90
95
  }
91
96
 
92
97
  destroy() {
93
- this.store._notificationManager.unsubscribe(this.#token);
94
- this.#relatedTokenMap.forEach((token) => {
98
+ this.store._notificationManager.unsubscribe(this.___token);
99
+ this.___relatedTokenMap.forEach((token) => {
95
100
  this.store._notificationManager.unsubscribe(token);
96
101
  });
97
- this.#relatedTokenMap.clear();
102
+ this.___relatedTokenMap.clear();
98
103
  }
99
104
 
100
105
  @cached
@@ -104,34 +109,44 @@ export default class HasManyReference {
104
109
 
105
110
  let resource = this._resource();
106
111
 
107
- this.#relatedTokenMap.forEach((token) => {
108
- this.store._notificationManager.unsubscribe(token);
109
- });
110
- this.#relatedTokenMap.clear();
112
+ let map = this.___relatedTokenMap;
113
+ this.___relatedTokenMap = new Map();
111
114
 
112
115
  if (resource && resource.data) {
113
116
  return resource.data.map((resourceIdentifier) => {
114
117
  const identifier = this.store.identifierCache.getOrCreateRecordIdentifier(resourceIdentifier);
115
- const token = this.store._notificationManager.subscribe(
116
- identifier,
117
- (_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
118
- if (bucket === 'identity' || ((bucket === 'attributes' || bucket === 'property') && notifiedKey === 'id')) {
119
- this._ref++;
118
+ let token = map.get(identifier);
119
+
120
+ if (token) {
121
+ map.delete(identifier);
122
+ } else {
123
+ token = this.store._notificationManager.subscribe(
124
+ identifier,
125
+ (_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
126
+ if (bucket === 'identity' || (bucket === 'attributes' && notifiedKey === 'id')) {
127
+ this._ref++;
128
+ }
120
129
  }
121
- }
122
- );
123
-
124
- this.#relatedTokenMap.set(identifier, token);
130
+ );
131
+ }
132
+ this.___relatedTokenMap.set(identifier, token);
125
133
 
126
134
  return identifier;
127
135
  });
128
136
  }
129
137
 
138
+ map.forEach((token) => {
139
+ this.store._notificationManager.unsubscribe(token);
140
+ });
141
+ map.clear();
142
+
130
143
  return [];
131
144
  }
132
145
 
133
146
  _resource() {
134
- return this.store._instanceCache.recordDataFor(this.#identifier, false).getHasMany(this.key);
147
+ return this.store._instanceCache
148
+ .getRecordData(this.___identifier)
149
+ .getRelationship(this.___identifier, this.key) as CollectionResourceRelationship;
135
150
  }
136
151
 
137
152
  /**
@@ -145,7 +160,7 @@ export default class HasManyReference {
145
160
  import Model, { hasMany } from '@ember-data/model';
146
161
 
147
162
  export default class PostModel extends Model {
148
- @hasMany({ async: true }) comments;
163
+ @hasMany('comment', { async: true, inverse: null }) comments;
149
164
  }
150
165
  ```
151
166
 
@@ -194,7 +209,7 @@ export default class HasManyReference {
194
209
  import Model, { hasMany } from '@ember-data/model';
195
210
 
196
211
  export default class PostModel extends Model {
197
- @hasMany({ async: true }) comments;
212
+ @hasMany('comment', { async: true, inverse: null }) comments;
198
213
  }
199
214
  ```
200
215
 
@@ -234,7 +249,7 @@ export default class HasManyReference {
234
249
  // models/blog.js
235
250
  import Model, { belongsTo } from '@ember-data/model';
236
251
  export default Model.extend({
237
- user: belongsTo({ async: true })
252
+ user: belongsTo('user', { async: true, inverse: null })
238
253
  });
239
254
 
240
255
  let blog = store.push({
@@ -296,7 +311,7 @@ export default class HasManyReference {
296
311
  // models/blog.js
297
312
  import Model, { hasMany } from '@ember-data/model';
298
313
  export default Model.extend({
299
- users: hasMany({ async: true })
314
+ users: hasMany('user', { async: true, inverse: null })
300
315
  });
301
316
 
302
317
  let blog = store.push({
@@ -347,7 +362,7 @@ export default class HasManyReference {
347
362
  import Model, { hasMany } from '@ember-data/model';
348
363
 
349
364
  export default class PostModel extends Model {
350
- @hasMany({ async: true }) comments;
365
+ @hasMany('comment', { async: true, inverse: null }) comments;
351
366
  }
352
367
  ```
353
368
 
@@ -384,7 +399,25 @@ export default class HasManyReference {
384
399
  async push(
385
400
  objectOrPromise: ExistingResourceObject[] | CollectionResourceDocument | { data: SingleResourceDocument[] }
386
401
  ): Promise<ManyArray> {
387
- const payload = await resolve(objectOrPromise);
402
+ let payload = objectOrPromise;
403
+ if (DEPRECATE_PROMISE_PROXIES && (objectOrPromise as unknown as { then: unknown }).then) {
404
+ payload = await resolve(objectOrPromise);
405
+ if (payload !== objectOrPromise) {
406
+ deprecate(
407
+ `You passed in a Promise to a Reference API that now expects a resolved value. await the value before setting it.`,
408
+ false,
409
+ {
410
+ id: 'ember-data:deprecate-promise-proxies',
411
+ until: '5.0',
412
+ since: {
413
+ enabled: '4.8',
414
+ available: '4.8',
415
+ },
416
+ for: 'ember-data',
417
+ }
418
+ );
419
+ }
420
+ }
388
421
  let array: Array<ExistingResourceObject | SingleResourceDocument>;
389
422
 
390
423
  if (!Array.isArray(payload) && typeof payload === 'object' && Array.isArray(payload.data)) {
@@ -414,9 +447,9 @@ export default class HasManyReference {
414
447
  return recordIdentifierFor(record);
415
448
  });
416
449
 
417
- const { graph, identifier } = this.hasManyRelationship;
418
- store._backburner.join(() => {
419
- graph.push({
450
+ const { identifier } = this.hasManyRelationship;
451
+ store._join(() => {
452
+ this.graph.push({
420
453
  op: 'replaceRelatedRecords',
421
454
  record: identifier,
422
455
  field: this.key,
@@ -433,18 +466,16 @@ export default class HasManyReference {
433
466
  return false;
434
467
  }
435
468
 
436
- let members = this.hasManyRelationship.currentState;
469
+ let localState = this.hasManyRelationship.localState;
437
470
 
438
- //TODO @runspired determine isLoaded via a better means
439
- return members.every((identifier) => {
440
- let internalModel = this.store._instanceCache._internalModelForResource(identifier);
441
- return internalModel.isLoaded === true;
471
+ return localState.every((identifier) => {
472
+ return this.store._instanceCache.recordIsLoaded(identifier, true) === true;
442
473
  });
443
474
  }
444
475
 
445
476
  /**
446
477
  `value()` synchronously returns the current value of the has-many
447
- relationship. Unlike `record.get('relationshipName')`, calling
478
+ relationship. Unlike `record.relationshipName`, calling
448
479
  `value()` on a reference does not trigger a fetch if the async
449
480
  relationship is not yet loaded. If the relationship is not loaded
450
481
  it will always return `null`.
@@ -455,7 +486,7 @@ export default class HasManyReference {
455
486
  import Model, { hasMany } from '@ember-data/model';
456
487
 
457
488
  export default class PostModel extends Model {
458
- @hasMany({ async: true }) comments;
489
+ @hasMany('comment', { async: true, inverse: null }) comments;
459
490
  }
460
491
  ```
461
492
 
@@ -474,7 +505,7 @@ export default class HasManyReference {
474
505
 
475
506
  let commentsRef = post.hasMany('comments');
476
507
 
477
- post.get('comments').then(function(comments) {
508
+ post.comments.then(function(comments) {
478
509
  commentsRef.value() === comments
479
510
  })
480
511
  ```
@@ -484,9 +515,9 @@ export default class HasManyReference {
484
515
  @return {ManyArray}
485
516
  */
486
517
  value() {
487
- const support: LegacySupport = (
488
- LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
489
- ).getWithError(this.#identifier);
518
+ const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
519
+ this.___identifier
520
+ )!;
490
521
 
491
522
  return this._isLoaded() ? support.getManyArray(this.key) : null;
492
523
  }
@@ -503,7 +534,7 @@ export default class HasManyReference {
503
534
  import Model, { hasMany } from '@ember-data/model';
504
535
 
505
536
  export default class PostModel extends Model {
506
- @hasMany({ async: true }) comments;
537
+ @hasMany('comment', { async: true, inverse: null }) comments;
507
538
  }
508
539
  ```
509
540
 
@@ -556,9 +587,9 @@ export default class HasManyReference {
556
587
  this has-many relationship.
557
588
  */
558
589
  async load(options?: FindOptions): Promise<ManyArray> {
559
- const support: LegacySupport = (
560
- LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
561
- ).getWithError(this.#identifier);
590
+ const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
591
+ this.___identifier
592
+ )!;
562
593
  return support.getHasMany(this.key, options) as Promise<ManyArray> | ManyArray; // this cast is necessary because typescript does not work properly with custom thenables;
563
594
  }
564
595
 
@@ -572,7 +603,7 @@ export default class HasManyReference {
572
603
  import Model, { hasMany } from '@ember-data/model';
573
604
 
574
605
  export default class PostModel extends Model {
575
- @hasMany({ async: true }) comments;
606
+ @hasMany('comment', { async: true, inverse: null }) comments;
576
607
  }
577
608
  ```
578
609
 
@@ -613,9 +644,9 @@ export default class HasManyReference {
613
644
  @return {Promise} a promise that resolves with the ManyArray in this has-many relationship.
614
645
  */
615
646
  reload(options?: FindOptions) {
616
- const support: LegacySupport = (
617
- LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
618
- ).getWithError(this.#identifier);
647
+ const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
648
+ this.___identifier
649
+ )!;
619
650
  return support.reloadHasMany(this.key, options);
620
651
  }
621
652
  }
@@ -1,17 +1,13 @@
1
+ import { dasherize } from '@ember/string';
1
2
  import { DEBUG } from '@glimmer/env';
2
3
 
3
4
  import { singularize } from 'ember-inflector';
4
5
 
5
6
  import type Store from '@ember-data/store';
6
- import { normalizeModelName } from '@ember-data/store/-private';
7
7
  import type { RelationshipSchema } from '@ember-data/types/q/record-data-schemas';
8
8
 
9
- /**
10
- @module @ember-data/store
11
- */
12
-
13
9
  function typeForRelationshipMeta(meta) {
14
- let modelName = normalizeModelName(meta.type || meta.key);
10
+ let modelName = dasherize(meta.type || meta.key);
15
11
 
16
12
  if (meta.kind === 'hasMany') {
17
13
  modelName = singularize(modelName);
@@ -25,10 +21,9 @@ function shouldFindInverse(relationshipMeta) {
25
21
  return !(options && options.inverse === null);
26
22
  }
27
23
 
28
- export class RelationshipDefinition implements RelationshipSchema {
24
+ class RelationshipDefinition implements RelationshipSchema {
29
25
  declare _type: string;
30
26
  declare __inverseKey: string;
31
- declare __inverseIsAsync: boolean;
32
27
  declare __hasCalculatedInverse: boolean;
33
28
  declare parentModelName: string;
34
29
  declare inverseIsAsync: string | null;
@@ -37,7 +32,6 @@ export class RelationshipDefinition implements RelationshipSchema {
37
32
  constructor(meta: any) {
38
33
  this._type = '';
39
34
  this.__inverseKey = '';
40
- this.__inverseIsAsync = true;
41
35
  this.__hasCalculatedInverse = false;
42
36
  this.parentModelName = meta.parentModelName;
43
37
  this.meta = meta;
@@ -74,40 +68,28 @@ export class RelationshipDefinition implements RelationshipSchema {
74
68
  return this.__inverseKey;
75
69
  }
76
70
 
77
- _inverseIsAsync(store: Store, modelClass): boolean {
78
- if (this.__hasCalculatedInverse === false) {
79
- this._calculateInverse(store, modelClass);
80
- }
81
- return this.__inverseIsAsync;
82
- }
83
-
84
71
  _calculateInverse(store: Store, modelClass): void {
85
72
  this.__hasCalculatedInverse = true;
86
- let inverseKey, inverseIsAsync;
73
+ let inverseKey;
87
74
  let inverse: any = null;
88
75
 
89
76
  if (shouldFindInverse(this.meta)) {
90
77
  inverse = modelClass.inverseFor(this.key, store);
91
- } else if (DEBUG) {
78
+ }
79
+ // TODO make this error again for the non-polymorphic case
80
+ if (DEBUG && !this.options.polymorphic) {
92
81
  modelClass.typeForRelationship(this.key, store);
93
82
  }
94
83
 
95
84
  if (inverse) {
96
85
  inverseKey = inverse.name;
97
- inverseIsAsync = isRelationshipAsync(inverse);
98
86
  } else {
99
87
  inverseKey = null;
100
- inverseIsAsync = false;
101
88
  }
102
89
  this.__inverseKey = inverseKey;
103
- this.__inverseIsAsync = inverseIsAsync;
104
90
  }
105
91
  }
106
-
107
- function isRelationshipAsync(meta: RelationshipSchema): boolean {
108
- let inverseAsync = meta.options && meta.options.async;
109
- return typeof inverseAsync === 'undefined' ? true : inverseAsync;
110
- }
92
+ export type { RelationshipDefinition };
111
93
 
112
94
  export function relationshipFromMeta(meta: RelationshipSchema): RelationshipDefinition {
113
95
  return new RelationshipDefinition(meta);
package/index.js CHANGED
@@ -17,8 +17,11 @@ module.exports = Object.assign({}, addonBaseConfig, {
17
17
  '@ember-data/store/-private',
18
18
  '@ember-data/store/-debug',
19
19
  '@embroider/macros',
20
+ '@ember/string',
20
21
  '@embroider/macros/es-compat',
21
22
 
23
+ '@ember/object/proxy',
24
+ '@ember/object/promise-proxy-mixin',
22
25
  '@ember/application',
23
26
  '@ember/array',
24
27
  '@ember/array/mutable',