@ember-data/model 4.8.0-alpha.2 → 4.8.0-alpha.5
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.
- package/addon/-private/attr.js +9 -24
- package/addon/-private/belongs-to.js +87 -25
- package/addon/-private/errors.ts +6 -6
- package/addon/-private/has-many.js +81 -21
- package/addon/-private/legacy-data-fetch.js +35 -13
- package/addon/-private/legacy-data-utils.ts +1 -1
- package/addon/-private/legacy-relationships-support.ts +138 -133
- package/addon/-private/many-array.ts +38 -26
- package/addon/-private/model.js +105 -99
- package/addon/-private/notify-changes.ts +2 -2
- package/addon/-private/promise-many-array.ts +170 -112
- package/addon/-private/record-state.ts +35 -33
- package/addon/-private/references/belongs-to.ts +44 -36
- package/addon/-private/references/has-many.ts +65 -54
- package/addon/-private/relationship-meta.ts +3 -23
- package/package.json +12 -8
|
@@ -4,12 +4,12 @@ import { cached, tracked } from '@glimmer/tracking';
|
|
|
4
4
|
import type { Object as JSONObject, Value as JSONValue } from 'json-typescript';
|
|
5
5
|
import { resolve } from 'rsvp';
|
|
6
6
|
|
|
7
|
-
import type {
|
|
7
|
+
import type { Graph } from '@ember-data/record-data/-private/graph';
|
|
8
|
+
import type BelongsToRelationship from '@ember-data/record-data/-private/relationships/state/belongs-to';
|
|
8
9
|
import type Store from '@ember-data/store';
|
|
9
10
|
import { assertPolymorphicType } from '@ember-data/store/-debug';
|
|
10
11
|
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';
|
|
12
|
+
import type { NotificationType } from '@ember-data/store/-private/managers/record-notification-manager';
|
|
13
13
|
import type {
|
|
14
14
|
LinkObject,
|
|
15
15
|
Links,
|
|
@@ -52,31 +52,34 @@ export default class BelongsToReference {
|
|
|
52
52
|
declare key: string;
|
|
53
53
|
declare belongsToRelationship: BelongsToRelationship;
|
|
54
54
|
declare type: string;
|
|
55
|
-
|
|
55
|
+
___identifier: StableRecordIdentifier;
|
|
56
56
|
declare store: Store;
|
|
57
|
+
declare graph: Graph;
|
|
57
58
|
|
|
58
59
|
// unsubscribe tokens given to us by the notification manager
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
___token!: object;
|
|
61
|
+
___relatedToken: object | null = null;
|
|
61
62
|
|
|
62
63
|
@tracked _ref = 0;
|
|
63
64
|
|
|
64
65
|
constructor(
|
|
65
66
|
store: Store,
|
|
67
|
+
graph: Graph,
|
|
66
68
|
parentIdentifier: StableRecordIdentifier,
|
|
67
69
|
belongsToRelationship: BelongsToRelationship,
|
|
68
70
|
key: string
|
|
69
71
|
) {
|
|
72
|
+
this.graph = graph;
|
|
70
73
|
this.key = key;
|
|
71
74
|
this.belongsToRelationship = belongsToRelationship;
|
|
72
75
|
this.type = belongsToRelationship.definition.type;
|
|
73
76
|
this.store = store;
|
|
74
|
-
this
|
|
77
|
+
this.___identifier = parentIdentifier;
|
|
75
78
|
|
|
76
|
-
this
|
|
79
|
+
this.___token = store._notificationManager.subscribe(
|
|
77
80
|
parentIdentifier,
|
|
78
81
|
(_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
|
|
79
|
-
if (
|
|
82
|
+
if (bucket === 'relationships' && notifiedKey === key) {
|
|
80
83
|
this._ref++;
|
|
81
84
|
}
|
|
82
85
|
}
|
|
@@ -88,9 +91,11 @@ export default class BelongsToReference {
|
|
|
88
91
|
destroy() {
|
|
89
92
|
// TODO @feature we need the notification manager often enough
|
|
90
93
|
// we should potentially just expose it fully public
|
|
91
|
-
this.store._notificationManager.unsubscribe(this
|
|
92
|
-
|
|
93
|
-
|
|
94
|
+
this.store._notificationManager.unsubscribe(this.___token);
|
|
95
|
+
this.___token = null as unknown as object;
|
|
96
|
+
if (this.___relatedToken) {
|
|
97
|
+
this.store._notificationManager.unsubscribe(this.___relatedToken);
|
|
98
|
+
this.___relatedToken = null;
|
|
94
99
|
}
|
|
95
100
|
}
|
|
96
101
|
|
|
@@ -98,17 +103,18 @@ export default class BelongsToReference {
|
|
|
98
103
|
@dependentKeyCompat
|
|
99
104
|
get _relatedIdentifier(): StableRecordIdentifier | null {
|
|
100
105
|
this._ref; // consume the tracked prop
|
|
101
|
-
if (this
|
|
102
|
-
this.store._notificationManager.unsubscribe(this
|
|
106
|
+
if (this.___relatedToken) {
|
|
107
|
+
this.store._notificationManager.unsubscribe(this.___relatedToken);
|
|
108
|
+
this.___relatedToken = null;
|
|
103
109
|
}
|
|
104
110
|
|
|
105
111
|
let resource = this._resource();
|
|
106
112
|
if (resource && resource.data) {
|
|
107
113
|
const identifier = this.store.identifierCache.getOrCreateRecordIdentifier(resource.data);
|
|
108
|
-
this
|
|
114
|
+
this.___relatedToken = this.store._notificationManager.subscribe(
|
|
109
115
|
identifier,
|
|
110
116
|
(_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
|
|
111
|
-
if (bucket === 'identity' || (
|
|
117
|
+
if (bucket === 'identity' || (bucket === 'attributes' && notifiedKey === 'id')) {
|
|
112
118
|
this._ref++;
|
|
113
119
|
}
|
|
114
120
|
}
|
|
@@ -125,7 +131,7 @@ export default class BelongsToReference {
|
|
|
125
131
|
`type()` and `id()` methods form a composite key for the identity
|
|
126
132
|
map. This can be used to access the id of an async relationship
|
|
127
133
|
without triggering a fetch that would normally happen if you
|
|
128
|
-
attempted to use `record.
|
|
134
|
+
attempted to use `record.relationship.id`.
|
|
129
135
|
|
|
130
136
|
Example
|
|
131
137
|
|
|
@@ -134,7 +140,7 @@ export default class BelongsToReference {
|
|
|
134
140
|
import Model, { belongsTo } from '@ember-data/model';
|
|
135
141
|
|
|
136
142
|
export default class BlogModel extends Model {
|
|
137
|
-
@belongsTo({ async: true }) user;
|
|
143
|
+
@belongsTo('user', { async: true, inverse: null }) user;
|
|
138
144
|
}
|
|
139
145
|
|
|
140
146
|
let blog = store.push({
|
|
@@ -174,7 +180,7 @@ export default class BelongsToReference {
|
|
|
174
180
|
// models/blog.js
|
|
175
181
|
import Model, { belongsTo } from '@ember-data/model';
|
|
176
182
|
export default Model.extend({
|
|
177
|
-
user: belongsTo({ async: true })
|
|
183
|
+
user: belongsTo('user', { async: true, inverse: null })
|
|
178
184
|
});
|
|
179
185
|
|
|
180
186
|
let blog = store.push({
|
|
@@ -236,7 +242,7 @@ export default class BelongsToReference {
|
|
|
236
242
|
// models/blog.js
|
|
237
243
|
import Model, { belongsTo } from '@ember-data/model';
|
|
238
244
|
export default Model.extend({
|
|
239
|
-
user: belongsTo({ async: true })
|
|
245
|
+
user: belongsTo('user', { async: true, inverse: null })
|
|
240
246
|
});
|
|
241
247
|
|
|
242
248
|
let blog = store.push({
|
|
@@ -277,7 +283,9 @@ export default class BelongsToReference {
|
|
|
277
283
|
}
|
|
278
284
|
|
|
279
285
|
_resource() {
|
|
280
|
-
return this.store._instanceCache
|
|
286
|
+
return this.store._instanceCache
|
|
287
|
+
.getRecordData(this.___identifier)
|
|
288
|
+
.getRelationship(this.___identifier, this.key) as SingleResourceRelationship;
|
|
281
289
|
}
|
|
282
290
|
|
|
283
291
|
/**
|
|
@@ -291,7 +299,7 @@ export default class BelongsToReference {
|
|
|
291
299
|
import Model, { hasMany } from '@ember-data/model';
|
|
292
300
|
|
|
293
301
|
export default class PostModel extends Model {
|
|
294
|
-
@hasMany({ async: true }) comments;
|
|
302
|
+
@hasMany('comment', { async: true, inverse: null }) comments;
|
|
295
303
|
}
|
|
296
304
|
```
|
|
297
305
|
|
|
@@ -341,7 +349,7 @@ export default class BelongsToReference {
|
|
|
341
349
|
import Model, { belongsTo } from '@ember-data/model';
|
|
342
350
|
|
|
343
351
|
export default class BlogModel extends Model {
|
|
344
|
-
@belongsTo({ async: true }) user;
|
|
352
|
+
@belongsTo('user', { async: true, inverse: null }) user;
|
|
345
353
|
}
|
|
346
354
|
|
|
347
355
|
let blog = store.push({
|
|
@@ -389,9 +397,9 @@ export default class BelongsToReference {
|
|
|
389
397
|
this.store
|
|
390
398
|
);
|
|
391
399
|
|
|
392
|
-
const {
|
|
393
|
-
this.store.
|
|
394
|
-
graph.push({
|
|
400
|
+
const { identifier } = this.belongsToRelationship;
|
|
401
|
+
this.store._join(() => {
|
|
402
|
+
this.graph.push({
|
|
395
403
|
op: 'replaceRelatedRecord',
|
|
396
404
|
record: identifier,
|
|
397
405
|
field: this.key,
|
|
@@ -404,7 +412,7 @@ export default class BelongsToReference {
|
|
|
404
412
|
|
|
405
413
|
/**
|
|
406
414
|
`value()` synchronously returns the current value of the belongs-to
|
|
407
|
-
relationship. Unlike `record.
|
|
415
|
+
relationship. Unlike `record.relationshipName`, calling
|
|
408
416
|
`value()` on a reference does not trigger a fetch if the async
|
|
409
417
|
relationship is not yet loaded. If the relationship is not loaded
|
|
410
418
|
it will always return `null`.
|
|
@@ -416,7 +424,7 @@ export default class BelongsToReference {
|
|
|
416
424
|
import Model, { belongsTo } from '@ember-data/model';
|
|
417
425
|
|
|
418
426
|
export default class BlogModel extends Model {
|
|
419
|
-
@belongsTo({ async: true }) user;
|
|
427
|
+
@belongsTo('user', { async: true, inverse: null }) user;
|
|
420
428
|
}
|
|
421
429
|
|
|
422
430
|
let blog = store.push({
|
|
@@ -469,7 +477,7 @@ export default class BelongsToReference {
|
|
|
469
477
|
import Model, { belongsTo } from '@ember-data/model';
|
|
470
478
|
|
|
471
479
|
export default class BlogModel extends Model {
|
|
472
|
-
@belongsTo({ async: true }) user;
|
|
480
|
+
@belongsTo('user', { async: true, inverse: null }) user;
|
|
473
481
|
}
|
|
474
482
|
|
|
475
483
|
let blog = store.push({
|
|
@@ -520,9 +528,9 @@ export default class BelongsToReference {
|
|
|
520
528
|
@return {Promise} a promise that resolves with the record in this belongs-to relationship.
|
|
521
529
|
*/
|
|
522
530
|
load(options?: Dict<unknown>) {
|
|
523
|
-
const support: LegacySupport = (
|
|
524
|
-
|
|
525
|
-
)
|
|
531
|
+
const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
|
|
532
|
+
this.___identifier
|
|
533
|
+
)!;
|
|
526
534
|
return support.getBelongsTo(this.key, options);
|
|
527
535
|
}
|
|
528
536
|
|
|
@@ -539,7 +547,7 @@ export default class BelongsToReference {
|
|
|
539
547
|
import Model, { belongsTo } from '@ember-data/model';
|
|
540
548
|
|
|
541
549
|
export default class BlogModel extends Model {
|
|
542
|
-
@belongsTo({ async: true }) user;
|
|
550
|
+
@belongsTo('user', { async: true, inverse: null }) user;
|
|
543
551
|
}
|
|
544
552
|
|
|
545
553
|
let blog = store.push({
|
|
@@ -577,9 +585,9 @@ export default class BelongsToReference {
|
|
|
577
585
|
@return {Promise} a promise that resolves with the record in this belongs-to relationship after the reload has completed.
|
|
578
586
|
*/
|
|
579
587
|
reload(options?: Dict<unknown>) {
|
|
580
|
-
const support: LegacySupport = (
|
|
581
|
-
|
|
582
|
-
)
|
|
588
|
+
const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
|
|
589
|
+
this.___identifier
|
|
590
|
+
)!;
|
|
583
591
|
return support.reloadBelongsTo(this.key, options).then(() => this.value());
|
|
584
592
|
}
|
|
585
593
|
}
|
|
@@ -7,12 +7,12 @@ import { resolve } from 'rsvp';
|
|
|
7
7
|
|
|
8
8
|
import { ManyArray } from 'ember-data/-private';
|
|
9
9
|
|
|
10
|
-
import type {
|
|
10
|
+
import type { Graph } from '@ember-data/record-data/-private/graph';
|
|
11
|
+
import type ManyRelationship from '@ember-data/record-data/-private/relationships/state/has-many';
|
|
11
12
|
import type Store from '@ember-data/store';
|
|
12
13
|
import { recordIdentifierFor } from '@ember-data/store';
|
|
13
14
|
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';
|
|
15
|
+
import type { NotificationType } from '@ember-data/store/-private/managers/record-notification-manager';
|
|
16
16
|
import type {
|
|
17
17
|
CollectionResourceDocument,
|
|
18
18
|
CollectionResourceRelationship,
|
|
@@ -53,48 +53,51 @@ function isResourceIdentiferWithRelatedLinks(
|
|
|
53
53
|
@extends Reference
|
|
54
54
|
*/
|
|
55
55
|
export default class HasManyReference {
|
|
56
|
+
declare graph: Graph;
|
|
56
57
|
declare key: string;
|
|
57
58
|
declare hasManyRelationship: ManyRelationship;
|
|
58
59
|
declare type: string;
|
|
59
60
|
declare store: Store;
|
|
60
61
|
|
|
61
62
|
// unsubscribe tokens given to us by the notification manager
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
___token!: Object;
|
|
64
|
+
___identifier: StableRecordIdentifier;
|
|
65
|
+
___relatedTokenMap!: Map<StableRecordIdentifier, Object>;
|
|
65
66
|
|
|
66
67
|
@tracked _ref = 0;
|
|
67
68
|
|
|
68
69
|
constructor(
|
|
69
70
|
store: Store,
|
|
71
|
+
graph: Graph,
|
|
70
72
|
parentIdentifier: StableRecordIdentifier,
|
|
71
73
|
hasManyRelationship: ManyRelationship,
|
|
72
74
|
key: string
|
|
73
75
|
) {
|
|
76
|
+
this.graph = graph;
|
|
74
77
|
this.key = key;
|
|
75
78
|
this.hasManyRelationship = hasManyRelationship;
|
|
76
79
|
this.type = hasManyRelationship.definition.type;
|
|
77
80
|
|
|
78
81
|
this.store = store;
|
|
79
|
-
this
|
|
80
|
-
this
|
|
82
|
+
this.___identifier = parentIdentifier;
|
|
83
|
+
this.___token = store._notificationManager.subscribe(
|
|
81
84
|
parentIdentifier,
|
|
82
85
|
(_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
|
|
83
|
-
if (
|
|
86
|
+
if (bucket === 'relationships' && notifiedKey === key) {
|
|
84
87
|
this._ref++;
|
|
85
88
|
}
|
|
86
89
|
}
|
|
87
90
|
);
|
|
88
|
-
this
|
|
91
|
+
this.___relatedTokenMap = new Map();
|
|
89
92
|
// TODO inverse
|
|
90
93
|
}
|
|
91
94
|
|
|
92
95
|
destroy() {
|
|
93
|
-
this.store._notificationManager.unsubscribe(this
|
|
94
|
-
this
|
|
96
|
+
this.store._notificationManager.unsubscribe(this.___token);
|
|
97
|
+
this.___relatedTokenMap.forEach((token) => {
|
|
95
98
|
this.store._notificationManager.unsubscribe(token);
|
|
96
99
|
});
|
|
97
|
-
this
|
|
100
|
+
this.___relatedTokenMap.clear();
|
|
98
101
|
}
|
|
99
102
|
|
|
100
103
|
@cached
|
|
@@ -104,34 +107,44 @@ export default class HasManyReference {
|
|
|
104
107
|
|
|
105
108
|
let resource = this._resource();
|
|
106
109
|
|
|
107
|
-
this
|
|
108
|
-
|
|
109
|
-
});
|
|
110
|
-
this.#relatedTokenMap.clear();
|
|
110
|
+
let map = this.___relatedTokenMap;
|
|
111
|
+
this.___relatedTokenMap = new Map();
|
|
111
112
|
|
|
112
113
|
if (resource && resource.data) {
|
|
113
114
|
return resource.data.map((resourceIdentifier) => {
|
|
114
115
|
const identifier = this.store.identifierCache.getOrCreateRecordIdentifier(resourceIdentifier);
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
116
|
+
let token = map.get(identifier);
|
|
117
|
+
|
|
118
|
+
if (token) {
|
|
119
|
+
map.delete(identifier);
|
|
120
|
+
} else {
|
|
121
|
+
token = this.store._notificationManager.subscribe(
|
|
122
|
+
identifier,
|
|
123
|
+
(_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
|
|
124
|
+
if (bucket === 'identity' || (bucket === 'attributes' && notifiedKey === 'id')) {
|
|
125
|
+
this._ref++;
|
|
126
|
+
}
|
|
120
127
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
this.#relatedTokenMap.set(identifier, token);
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
this.___relatedTokenMap.set(identifier, token);
|
|
125
131
|
|
|
126
132
|
return identifier;
|
|
127
133
|
});
|
|
128
134
|
}
|
|
129
135
|
|
|
136
|
+
map.forEach((token) => {
|
|
137
|
+
this.store._notificationManager.unsubscribe(token);
|
|
138
|
+
});
|
|
139
|
+
map.clear();
|
|
140
|
+
|
|
130
141
|
return [];
|
|
131
142
|
}
|
|
132
143
|
|
|
133
144
|
_resource() {
|
|
134
|
-
return this.store._instanceCache
|
|
145
|
+
return this.store._instanceCache
|
|
146
|
+
.getRecordData(this.___identifier)
|
|
147
|
+
.getRelationship(this.___identifier, this.key) as CollectionResourceRelationship;
|
|
135
148
|
}
|
|
136
149
|
|
|
137
150
|
/**
|
|
@@ -145,7 +158,7 @@ export default class HasManyReference {
|
|
|
145
158
|
import Model, { hasMany } from '@ember-data/model';
|
|
146
159
|
|
|
147
160
|
export default class PostModel extends Model {
|
|
148
|
-
@hasMany({ async: true }) comments;
|
|
161
|
+
@hasMany('comment', { async: true, inverse: null }) comments;
|
|
149
162
|
}
|
|
150
163
|
```
|
|
151
164
|
|
|
@@ -194,7 +207,7 @@ export default class HasManyReference {
|
|
|
194
207
|
import Model, { hasMany } from '@ember-data/model';
|
|
195
208
|
|
|
196
209
|
export default class PostModel extends Model {
|
|
197
|
-
@hasMany({ async: true }) comments;
|
|
210
|
+
@hasMany('comment', { async: true, inverse: null }) comments;
|
|
198
211
|
}
|
|
199
212
|
```
|
|
200
213
|
|
|
@@ -234,7 +247,7 @@ export default class HasManyReference {
|
|
|
234
247
|
// models/blog.js
|
|
235
248
|
import Model, { belongsTo } from '@ember-data/model';
|
|
236
249
|
export default Model.extend({
|
|
237
|
-
user: belongsTo({ async: true })
|
|
250
|
+
user: belongsTo('user', { async: true, inverse: null })
|
|
238
251
|
});
|
|
239
252
|
|
|
240
253
|
let blog = store.push({
|
|
@@ -296,7 +309,7 @@ export default class HasManyReference {
|
|
|
296
309
|
// models/blog.js
|
|
297
310
|
import Model, { hasMany } from '@ember-data/model';
|
|
298
311
|
export default Model.extend({
|
|
299
|
-
users: hasMany({ async: true })
|
|
312
|
+
users: hasMany('user', { async: true, inverse: null })
|
|
300
313
|
});
|
|
301
314
|
|
|
302
315
|
let blog = store.push({
|
|
@@ -347,7 +360,7 @@ export default class HasManyReference {
|
|
|
347
360
|
import Model, { hasMany } from '@ember-data/model';
|
|
348
361
|
|
|
349
362
|
export default class PostModel extends Model {
|
|
350
|
-
@hasMany({ async: true }) comments;
|
|
363
|
+
@hasMany('comment', { async: true, inverse: null }) comments;
|
|
351
364
|
}
|
|
352
365
|
```
|
|
353
366
|
|
|
@@ -414,9 +427,9 @@ export default class HasManyReference {
|
|
|
414
427
|
return recordIdentifierFor(record);
|
|
415
428
|
});
|
|
416
429
|
|
|
417
|
-
const {
|
|
418
|
-
store.
|
|
419
|
-
graph.push({
|
|
430
|
+
const { identifier } = this.hasManyRelationship;
|
|
431
|
+
store._join(() => {
|
|
432
|
+
this.graph.push({
|
|
420
433
|
op: 'replaceRelatedRecords',
|
|
421
434
|
record: identifier,
|
|
422
435
|
field: this.key,
|
|
@@ -433,18 +446,16 @@ export default class HasManyReference {
|
|
|
433
446
|
return false;
|
|
434
447
|
}
|
|
435
448
|
|
|
436
|
-
let
|
|
449
|
+
let localState = this.hasManyRelationship.localState;
|
|
437
450
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
let internalModel = this.store._instanceCache._internalModelForResource(identifier);
|
|
441
|
-
return internalModel.isLoaded === true;
|
|
451
|
+
return localState.every((identifier) => {
|
|
452
|
+
return this.store._instanceCache.recordIsLoaded(identifier, true) === true;
|
|
442
453
|
});
|
|
443
454
|
}
|
|
444
455
|
|
|
445
456
|
/**
|
|
446
457
|
`value()` synchronously returns the current value of the has-many
|
|
447
|
-
relationship. Unlike `record.
|
|
458
|
+
relationship. Unlike `record.relationshipName`, calling
|
|
448
459
|
`value()` on a reference does not trigger a fetch if the async
|
|
449
460
|
relationship is not yet loaded. If the relationship is not loaded
|
|
450
461
|
it will always return `null`.
|
|
@@ -455,7 +466,7 @@ export default class HasManyReference {
|
|
|
455
466
|
import Model, { hasMany } from '@ember-data/model';
|
|
456
467
|
|
|
457
468
|
export default class PostModel extends Model {
|
|
458
|
-
@hasMany({ async: true }) comments;
|
|
469
|
+
@hasMany('comment', { async: true, inverse: null }) comments;
|
|
459
470
|
}
|
|
460
471
|
```
|
|
461
472
|
|
|
@@ -474,7 +485,7 @@ export default class HasManyReference {
|
|
|
474
485
|
|
|
475
486
|
let commentsRef = post.hasMany('comments');
|
|
476
487
|
|
|
477
|
-
post.
|
|
488
|
+
post.comments.then(function(comments) {
|
|
478
489
|
commentsRef.value() === comments
|
|
479
490
|
})
|
|
480
491
|
```
|
|
@@ -484,9 +495,9 @@ export default class HasManyReference {
|
|
|
484
495
|
@return {ManyArray}
|
|
485
496
|
*/
|
|
486
497
|
value() {
|
|
487
|
-
const support: LegacySupport = (
|
|
488
|
-
|
|
489
|
-
)
|
|
498
|
+
const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
|
|
499
|
+
this.___identifier
|
|
500
|
+
)!;
|
|
490
501
|
|
|
491
502
|
return this._isLoaded() ? support.getManyArray(this.key) : null;
|
|
492
503
|
}
|
|
@@ -503,7 +514,7 @@ export default class HasManyReference {
|
|
|
503
514
|
import Model, { hasMany } from '@ember-data/model';
|
|
504
515
|
|
|
505
516
|
export default class PostModel extends Model {
|
|
506
|
-
@hasMany({ async: true }) comments;
|
|
517
|
+
@hasMany('comment', { async: true, inverse: null }) comments;
|
|
507
518
|
}
|
|
508
519
|
```
|
|
509
520
|
|
|
@@ -556,9 +567,9 @@ export default class HasManyReference {
|
|
|
556
567
|
this has-many relationship.
|
|
557
568
|
*/
|
|
558
569
|
async load(options?: FindOptions): Promise<ManyArray> {
|
|
559
|
-
const support: LegacySupport = (
|
|
560
|
-
|
|
561
|
-
)
|
|
570
|
+
const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
|
|
571
|
+
this.___identifier
|
|
572
|
+
)!;
|
|
562
573
|
return support.getHasMany(this.key, options) as Promise<ManyArray> | ManyArray; // this cast is necessary because typescript does not work properly with custom thenables;
|
|
563
574
|
}
|
|
564
575
|
|
|
@@ -572,7 +583,7 @@ export default class HasManyReference {
|
|
|
572
583
|
import Model, { hasMany } from '@ember-data/model';
|
|
573
584
|
|
|
574
585
|
export default class PostModel extends Model {
|
|
575
|
-
@hasMany({ async: true }) comments;
|
|
586
|
+
@hasMany('comment', { async: true, inverse: null }) comments;
|
|
576
587
|
}
|
|
577
588
|
```
|
|
578
589
|
|
|
@@ -613,9 +624,9 @@ export default class HasManyReference {
|
|
|
613
624
|
@return {Promise} a promise that resolves with the ManyArray in this has-many relationship.
|
|
614
625
|
*/
|
|
615
626
|
reload(options?: FindOptions) {
|
|
616
|
-
const support: LegacySupport = (
|
|
617
|
-
|
|
618
|
-
)
|
|
627
|
+
const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
|
|
628
|
+
this.___identifier
|
|
629
|
+
)!;
|
|
619
630
|
return support.reloadHasMany(this.key, options);
|
|
620
631
|
}
|
|
621
632
|
}
|
|
@@ -6,10 +6,6 @@ import { singularize } from 'ember-inflector';
|
|
|
6
6
|
import type Store from '@ember-data/store';
|
|
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
10
|
let modelName = dasherize(meta.type || meta.key);
|
|
15
11
|
|
|
@@ -25,10 +21,9 @@ function shouldFindInverse(relationshipMeta) {
|
|
|
25
21
|
return !(options && options.inverse === null);
|
|
26
22
|
}
|
|
27
23
|
|
|
28
|
-
|
|
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,16 +68,9 @@ 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
|
|
73
|
+
let inverseKey;
|
|
87
74
|
let inverse: any = null;
|
|
88
75
|
|
|
89
76
|
if (shouldFindInverse(this.meta)) {
|
|
@@ -94,20 +81,13 @@ export class RelationshipDefinition implements RelationshipSchema {
|
|
|
94
81
|
|
|
95
82
|
if (inverse) {
|
|
96
83
|
inverseKey = inverse.name;
|
|
97
|
-
inverseIsAsync = isRelationshipAsync(inverse);
|
|
98
84
|
} else {
|
|
99
85
|
inverseKey = null;
|
|
100
|
-
inverseIsAsync = false;
|
|
101
86
|
}
|
|
102
87
|
this.__inverseKey = inverseKey;
|
|
103
|
-
this.__inverseIsAsync = inverseIsAsync;
|
|
104
88
|
}
|
|
105
89
|
}
|
|
106
|
-
|
|
107
|
-
function isRelationshipAsync(meta: RelationshipSchema): boolean {
|
|
108
|
-
let inverseAsync = meta.options && meta.options.async;
|
|
109
|
-
return typeof inverseAsync === 'undefined' ? true : inverseAsync;
|
|
110
|
-
}
|
|
90
|
+
export type { RelationshipDefinition };
|
|
111
91
|
|
|
112
92
|
export function relationshipFromMeta(meta: RelationshipSchema): RelationshipDefinition {
|
|
113
93
|
return new RelationshipDefinition(meta);
|
package/package.json
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ember-data/model",
|
|
3
|
-
"version": "4.8.0-alpha.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "4.8.0-alpha.5",
|
|
4
|
+
"description": "A presentation layer for apps built with @ember-data/store",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ember-addon"
|
|
7
7
|
],
|
|
8
|
-
"repository":
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+ssh://git@github.com:emberjs/data.git",
|
|
11
|
+
"directory": "packages/model"
|
|
12
|
+
},
|
|
9
13
|
"license": "MIT",
|
|
10
14
|
"author": "",
|
|
11
15
|
"directories": {
|
|
@@ -18,9 +22,9 @@
|
|
|
18
22
|
"test:node": "mocha"
|
|
19
23
|
},
|
|
20
24
|
"dependencies": {
|
|
21
|
-
"@ember-data/canary-features": "4.8.0-alpha.
|
|
22
|
-
"@ember-data/private-build-infra": "4.8.0-alpha.
|
|
23
|
-
"@ember-data/store": "4.8.0-alpha.
|
|
25
|
+
"@ember-data/canary-features": "4.8.0-alpha.5",
|
|
26
|
+
"@ember-data/private-build-infra": "4.8.0-alpha.5",
|
|
27
|
+
"@ember-data/store": "4.8.0-alpha.5",
|
|
24
28
|
"@ember/edition-utils": "^1.2.0",
|
|
25
29
|
"@ember/string": "^3.0.0",
|
|
26
30
|
"@embroider/macros": "^1.8.3",
|
|
@@ -34,7 +38,7 @@
|
|
|
34
38
|
"inflection": "~1.13.2"
|
|
35
39
|
},
|
|
36
40
|
"devDependencies": {
|
|
37
|
-
"@ember-data/unpublished-test-infra": "4.8.0-alpha.
|
|
41
|
+
"@ember-data/unpublished-test-infra": "4.8.0-alpha.5",
|
|
38
42
|
"@ember/optional-features": "^2.0.0",
|
|
39
43
|
"@ember/test-helpers": "~2.7.0",
|
|
40
44
|
"broccoli-asset-rev": "^3.0.0",
|
|
@@ -67,7 +71,7 @@
|
|
|
67
71
|
"configPath": "tests/dummy/config"
|
|
68
72
|
},
|
|
69
73
|
"volta": {
|
|
70
|
-
"node": "16.
|
|
74
|
+
"node": "16.17.0",
|
|
71
75
|
"yarn": "1.22.19"
|
|
72
76
|
}
|
|
73
77
|
}
|