@ember-data/model 4.8.0-alpha.3 → 4.8.0-alpha.4

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.
@@ -247,10 +247,6 @@ export default class RecordState {
247
247
  this.notify('isEmpty');
248
248
  this.notify('isDirty');
249
249
  break;
250
- case 'unload':
251
- this.notify('isNew');
252
- this.notify('isDeleted');
253
- break;
254
250
  case 'errors':
255
251
  this.updateInvalidErrors(this.record.errors);
256
252
  this.notify('isValid');
@@ -326,7 +322,7 @@ export default class RecordState {
326
322
  let rd = this.recordData;
327
323
  if (this.isDeleted) {
328
324
  assert(`Expected RecordData to implement isDeletionCommitted()`, rd.isDeletionCommitted);
329
- return rd.isDeletionCommitted();
325
+ return rd.isDeletionCommitted(this.identifier);
330
326
  }
331
327
  if (this.isNew || this.isEmpty || !this.isValid || this.isDirty || this.isLoading) {
332
328
  return false;
@@ -340,21 +336,21 @@ export default class RecordState {
340
336
  // TODO this is not actually an RFC'd concept. Determine the
341
337
  // correct heuristic to replace this with.
342
338
  assert(`Expected RecordData to implement isEmpty()`, rd.isEmpty);
343
- return !this.isNew && rd.isEmpty();
339
+ return !this.isNew && rd.isEmpty(this.identifier);
344
340
  }
345
341
 
346
342
  @tagged
347
343
  get isNew() {
348
344
  let rd = this.recordData;
349
345
  assert(`Expected RecordData to implement isNew()`, rd.isNew);
350
- return rd.isNew();
346
+ return rd.isNew(this.identifier);
351
347
  }
352
348
 
353
349
  @tagged
354
350
  get isDeleted() {
355
351
  let rd = this.recordData;
356
352
  assert(`Expected RecordData to implement isDeleted()`, rd.isDeleted);
357
- return rd.isDeleted();
353
+ return rd.isDeleted(this.identifier);
358
354
  }
359
355
 
360
356
  @tagged
@@ -365,12 +361,10 @@ export default class RecordState {
365
361
  @tagged
366
362
  get isDirty() {
367
363
  let rd = this.recordData;
368
- assert(`Expected RecordData to implement hasChangedAttributes()`, rd.hasChangedAttributes);
369
- assert(`Expected RecordData to implement isDeletionCommitted()`, rd.isDeletionCommitted);
370
- if (rd.isDeletionCommitted() || (this.isDeleted && this.isNew)) {
364
+ if (rd.isDeletionCommitted(this.identifier) || (this.isDeleted && this.isNew)) {
371
365
  return false;
372
366
  }
373
- return this.isNew || rd.hasChangedAttributes();
367
+ return this.isNew || rd.hasChangedAttrs(this.identifier);
374
368
  }
375
369
 
376
370
  @tagged
@@ -52,12 +52,12 @@ export default class BelongsToReference {
52
52
  declare key: string;
53
53
  declare belongsToRelationship: BelongsToRelationship;
54
54
  declare type: string;
55
- #identifier: StableRecordIdentifier;
55
+ ___identifier: StableRecordIdentifier;
56
56
  declare store: Store;
57
57
 
58
58
  // unsubscribe tokens given to us by the notification manager
59
- #token!: Object;
60
- #relatedToken: Object | null = null;
59
+ ___token!: object;
60
+ ___relatedToken: object | null = null;
61
61
 
62
62
  @tracked _ref = 0;
63
63
 
@@ -71,12 +71,12 @@ export default class BelongsToReference {
71
71
  this.belongsToRelationship = belongsToRelationship;
72
72
  this.type = belongsToRelationship.definition.type;
73
73
  this.store = store;
74
- this.#identifier = parentIdentifier;
74
+ this.___identifier = parentIdentifier;
75
75
 
76
- this.#token = store._notificationManager.subscribe(
76
+ this.___token = store._notificationManager.subscribe(
77
77
  parentIdentifier,
78
78
  (_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
79
- if ((bucket === 'relationships' || bucket === 'property') && notifiedKey === key) {
79
+ if (bucket === 'relationships' && notifiedKey === key) {
80
80
  this._ref++;
81
81
  }
82
82
  }
@@ -88,9 +88,11 @@ export default class BelongsToReference {
88
88
  destroy() {
89
89
  // TODO @feature we need the notification manager often enough
90
90
  // 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);
91
+ this.store._notificationManager.unsubscribe(this.___token);
92
+ this.___token = null as unknown as object;
93
+ if (this.___relatedToken) {
94
+ this.store._notificationManager.unsubscribe(this.___relatedToken);
95
+ this.___relatedToken = null;
94
96
  }
95
97
  }
96
98
 
@@ -98,17 +100,18 @@ export default class BelongsToReference {
98
100
  @dependentKeyCompat
99
101
  get _relatedIdentifier(): StableRecordIdentifier | null {
100
102
  this._ref; // consume the tracked prop
101
- if (this.#relatedToken) {
102
- this.store._notificationManager.unsubscribe(this.#relatedToken);
103
+ if (this.___relatedToken) {
104
+ this.store._notificationManager.unsubscribe(this.___relatedToken);
105
+ this.___relatedToken = null;
103
106
  }
104
107
 
105
108
  let resource = this._resource();
106
109
  if (resource && resource.data) {
107
110
  const identifier = this.store.identifierCache.getOrCreateRecordIdentifier(resource.data);
108
- this.#relatedToken = this.store._notificationManager.subscribe(
111
+ this.___relatedToken = this.store._notificationManager.subscribe(
109
112
  identifier,
110
113
  (_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
111
- if (bucket === 'identity' || ((bucket === 'attributes' || bucket === 'property') && notifiedKey === 'id')) {
114
+ if (bucket === 'identity' || (bucket === 'attributes' && notifiedKey === 'id')) {
112
115
  this._ref++;
113
116
  }
114
117
  }
@@ -134,7 +137,7 @@ export default class BelongsToReference {
134
137
  import Model, { belongsTo } from '@ember-data/model';
135
138
 
136
139
  export default class BlogModel extends Model {
137
- @belongsTo({ async: true }) user;
140
+ @belongsTo('user', { async: true, inverse: null }) user;
138
141
  }
139
142
 
140
143
  let blog = store.push({
@@ -174,7 +177,7 @@ export default class BelongsToReference {
174
177
  // models/blog.js
175
178
  import Model, { belongsTo } from '@ember-data/model';
176
179
  export default Model.extend({
177
- user: belongsTo({ async: true })
180
+ user: belongsTo('user', { async: true, inverse: null })
178
181
  });
179
182
 
180
183
  let blog = store.push({
@@ -236,7 +239,7 @@ export default class BelongsToReference {
236
239
  // models/blog.js
237
240
  import Model, { belongsTo } from '@ember-data/model';
238
241
  export default Model.extend({
239
- user: belongsTo({ async: true })
242
+ user: belongsTo('user', { async: true, inverse: null })
240
243
  });
241
244
 
242
245
  let blog = store.push({
@@ -277,7 +280,9 @@ export default class BelongsToReference {
277
280
  }
278
281
 
279
282
  _resource() {
280
- return this.store._instanceCache.getRecordData(this.#identifier).getBelongsTo(this.key);
283
+ return this.store._instanceCache
284
+ .getRecordData(this.___identifier)
285
+ .getRelationship(this.___identifier, this.key) as SingleResourceRelationship;
281
286
  }
282
287
 
283
288
  /**
@@ -291,7 +296,7 @@ export default class BelongsToReference {
291
296
  import Model, { hasMany } from '@ember-data/model';
292
297
 
293
298
  export default class PostModel extends Model {
294
- @hasMany({ async: true }) comments;
299
+ @hasMany('comment', { async: true, inverse: null }) comments;
295
300
  }
296
301
  ```
297
302
 
@@ -341,7 +346,7 @@ export default class BelongsToReference {
341
346
  import Model, { belongsTo } from '@ember-data/model';
342
347
 
343
348
  export default class BlogModel extends Model {
344
- @belongsTo({ async: true }) user;
349
+ @belongsTo('user', { async: true, inverse: null }) user;
345
350
  }
346
351
 
347
352
  let blog = store.push({
@@ -416,7 +421,7 @@ export default class BelongsToReference {
416
421
  import Model, { belongsTo } from '@ember-data/model';
417
422
 
418
423
  export default class BlogModel extends Model {
419
- @belongsTo({ async: true }) user;
424
+ @belongsTo('user', { async: true, inverse: null }) user;
420
425
  }
421
426
 
422
427
  let blog = store.push({
@@ -469,7 +474,7 @@ export default class BelongsToReference {
469
474
  import Model, { belongsTo } from '@ember-data/model';
470
475
 
471
476
  export default class BlogModel extends Model {
472
- @belongsTo({ async: true }) user;
477
+ @belongsTo('user', { async: true, inverse: null }) user;
473
478
  }
474
479
 
475
480
  let blog = store.push({
@@ -522,7 +527,7 @@ export default class BelongsToReference {
522
527
  load(options?: Dict<unknown>) {
523
528
  const support: LegacySupport = (
524
529
  LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
525
- ).getWithError(this.#identifier);
530
+ ).getWithError(this.___identifier);
526
531
  return support.getBelongsTo(this.key, options);
527
532
  }
528
533
 
@@ -539,7 +544,7 @@ export default class BelongsToReference {
539
544
  import Model, { belongsTo } from '@ember-data/model';
540
545
 
541
546
  export default class BlogModel extends Model {
542
- @belongsTo({ async: true }) user;
547
+ @belongsTo('user', { async: true, inverse: null }) user;
543
548
  }
544
549
 
545
550
  let blog = store.push({
@@ -579,7 +584,7 @@ export default class BelongsToReference {
579
584
  reload(options?: Dict<unknown>) {
580
585
  const support: LegacySupport = (
581
586
  LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
582
- ).getWithError(this.#identifier);
587
+ ).getWithError(this.___identifier);
583
588
  return support.reloadBelongsTo(this.key, options).then(() => this.value());
584
589
  }
585
590
  }
@@ -59,9 +59,9 @@ export default class HasManyReference {
59
59
  declare store: Store;
60
60
 
61
61
  // unsubscribe tokens given to us by the notification manager
62
- #token!: Object;
63
- #identifier: StableRecordIdentifier;
64
- #relatedTokenMap!: Map<StableRecordIdentifier, Object>;
62
+ ___token!: Object;
63
+ ___identifier: StableRecordIdentifier;
64
+ ___relatedTokenMap!: Map<StableRecordIdentifier, Object>;
65
65
 
66
66
  @tracked _ref = 0;
67
67
 
@@ -76,25 +76,25 @@ export default class HasManyReference {
76
76
  this.type = hasManyRelationship.definition.type;
77
77
 
78
78
  this.store = store;
79
- this.#identifier = parentIdentifier;
80
- this.#token = store._notificationManager.subscribe(
79
+ this.___identifier = parentIdentifier;
80
+ this.___token = store._notificationManager.subscribe(
81
81
  parentIdentifier,
82
82
  (_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
83
- if ((bucket === 'relationships' || bucket === 'property') && notifiedKey === key) {
83
+ if (bucket === 'relationships' && notifiedKey === key) {
84
84
  this._ref++;
85
85
  }
86
86
  }
87
87
  );
88
- this.#relatedTokenMap = new Map();
88
+ this.___relatedTokenMap = new Map();
89
89
  // TODO inverse
90
90
  }
91
91
 
92
92
  destroy() {
93
- this.store._notificationManager.unsubscribe(this.#token);
94
- this.#relatedTokenMap.forEach((token) => {
93
+ this.store._notificationManager.unsubscribe(this.___token);
94
+ this.___relatedTokenMap.forEach((token) => {
95
95
  this.store._notificationManager.unsubscribe(token);
96
96
  });
97
- this.#relatedTokenMap.clear();
97
+ this.___relatedTokenMap.clear();
98
98
  }
99
99
 
100
100
  @cached
@@ -104,34 +104,44 @@ export default class HasManyReference {
104
104
 
105
105
  let resource = this._resource();
106
106
 
107
- this.#relatedTokenMap.forEach((token) => {
108
- this.store._notificationManager.unsubscribe(token);
109
- });
110
- this.#relatedTokenMap.clear();
107
+ let map = this.___relatedTokenMap;
108
+ this.___relatedTokenMap = new Map();
111
109
 
112
110
  if (resource && resource.data) {
113
111
  return resource.data.map((resourceIdentifier) => {
114
112
  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++;
113
+ let token = map.get(identifier);
114
+
115
+ if (token) {
116
+ map.delete(identifier);
117
+ } else {
118
+ token = this.store._notificationManager.subscribe(
119
+ identifier,
120
+ (_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
121
+ if (bucket === 'identity' || (bucket === 'attributes' && notifiedKey === 'id')) {
122
+ this._ref++;
123
+ }
120
124
  }
121
- }
122
- );
123
-
124
- this.#relatedTokenMap.set(identifier, token);
125
+ );
126
+ }
127
+ this.___relatedTokenMap.set(identifier, token);
125
128
 
126
129
  return identifier;
127
130
  });
128
131
  }
129
132
 
133
+ map.forEach((token) => {
134
+ this.store._notificationManager.unsubscribe(token);
135
+ });
136
+ map.clear();
137
+
130
138
  return [];
131
139
  }
132
140
 
133
141
  _resource() {
134
- return this.store._instanceCache.getRecordData(this.#identifier).getHasMany(this.key);
142
+ return this.store._instanceCache
143
+ .getRecordData(this.___identifier)
144
+ .getRelationship(this.___identifier, this.key) as CollectionResourceRelationship;
135
145
  }
136
146
 
137
147
  /**
@@ -145,7 +155,7 @@ export default class HasManyReference {
145
155
  import Model, { hasMany } from '@ember-data/model';
146
156
 
147
157
  export default class PostModel extends Model {
148
- @hasMany({ async: true }) comments;
158
+ @hasMany('comment', { async: true, inverse: null }) comments;
149
159
  }
150
160
  ```
151
161
 
@@ -194,7 +204,7 @@ export default class HasManyReference {
194
204
  import Model, { hasMany } from '@ember-data/model';
195
205
 
196
206
  export default class PostModel extends Model {
197
- @hasMany({ async: true }) comments;
207
+ @hasMany('comment', { async: true, inverse: null }) comments;
198
208
  }
199
209
  ```
200
210
 
@@ -234,7 +244,7 @@ export default class HasManyReference {
234
244
  // models/blog.js
235
245
  import Model, { belongsTo } from '@ember-data/model';
236
246
  export default Model.extend({
237
- user: belongsTo({ async: true })
247
+ user: belongsTo('user', { async: true, inverse: null })
238
248
  });
239
249
 
240
250
  let blog = store.push({
@@ -296,7 +306,7 @@ export default class HasManyReference {
296
306
  // models/blog.js
297
307
  import Model, { hasMany } from '@ember-data/model';
298
308
  export default Model.extend({
299
- users: hasMany({ async: true })
309
+ users: hasMany('user', { async: true, inverse: null })
300
310
  });
301
311
 
302
312
  let blog = store.push({
@@ -347,7 +357,7 @@ export default class HasManyReference {
347
357
  import Model, { hasMany } from '@ember-data/model';
348
358
 
349
359
  export default class PostModel extends Model {
350
- @hasMany({ async: true }) comments;
360
+ @hasMany('comment', { async: true, inverse: null }) comments;
351
361
  }
352
362
  ```
353
363
 
@@ -453,7 +463,7 @@ export default class HasManyReference {
453
463
  import Model, { hasMany } from '@ember-data/model';
454
464
 
455
465
  export default class PostModel extends Model {
456
- @hasMany({ async: true }) comments;
466
+ @hasMany('comment', { async: true, inverse: null }) comments;
457
467
  }
458
468
  ```
459
469
 
@@ -484,7 +494,7 @@ export default class HasManyReference {
484
494
  value() {
485
495
  const support: LegacySupport = (
486
496
  LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
487
- ).getWithError(this.#identifier);
497
+ ).getWithError(this.___identifier);
488
498
 
489
499
  return this._isLoaded() ? support.getManyArray(this.key) : null;
490
500
  }
@@ -501,7 +511,7 @@ export default class HasManyReference {
501
511
  import Model, { hasMany } from '@ember-data/model';
502
512
 
503
513
  export default class PostModel extends Model {
504
- @hasMany({ async: true }) comments;
514
+ @hasMany('comment', { async: true, inverse: null }) comments;
505
515
  }
506
516
  ```
507
517
 
@@ -556,7 +566,7 @@ export default class HasManyReference {
556
566
  async load(options?: FindOptions): Promise<ManyArray> {
557
567
  const support: LegacySupport = (
558
568
  LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
559
- ).getWithError(this.#identifier);
569
+ ).getWithError(this.___identifier);
560
570
  return support.getHasMany(this.key, options) as Promise<ManyArray> | ManyArray; // this cast is necessary because typescript does not work properly with custom thenables;
561
571
  }
562
572
 
@@ -570,7 +580,7 @@ export default class HasManyReference {
570
580
  import Model, { hasMany } from '@ember-data/model';
571
581
 
572
582
  export default class PostModel extends Model {
573
- @hasMany({ async: true }) comments;
583
+ @hasMany('comment', { async: true, inverse: null }) comments;
574
584
  }
575
585
  ```
576
586
 
@@ -613,7 +623,7 @@ export default class HasManyReference {
613
623
  reload(options?: FindOptions) {
614
624
  const support: LegacySupport = (
615
625
  LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
616
- ).getWithError(this.#identifier);
626
+ ).getWithError(this.___identifier);
617
627
  return support.reloadHasMany(this.key, options);
618
628
  }
619
629
  }
@@ -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
- 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,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, inverseIsAsync;
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.3",
4
- "description": "The default blueprint for ember-cli addons.",
3
+ "version": "4.8.0-alpha.4",
4
+ "description": "A presentation layer for apps built with @ember-data/store",
5
5
  "keywords": [
6
6
  "ember-addon"
7
7
  ],
8
- "repository": "https://github.com/emberjs/data/tree/master/packages/model",
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.3",
22
- "@ember-data/private-build-infra": "4.8.0-alpha.3",
23
- "@ember-data/store": "4.8.0-alpha.3",
25
+ "@ember-data/canary-features": "4.8.0-alpha.4",
26
+ "@ember-data/private-build-infra": "4.8.0-alpha.4",
27
+ "@ember-data/store": "4.8.0-alpha.4",
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.3",
41
+ "@ember-data/unpublished-test-infra": "4.8.0-alpha.4",
38
42
  "@ember/optional-features": "^2.0.0",
39
43
  "@ember/test-helpers": "~2.7.0",
40
44
  "broccoli-asset-rev": "^3.0.0",