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

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,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';
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
17
  import type { NotificationType } from '@ember-data/store/-private/managers/record-notification-manager';
15
- import type { DebugWeakCache } from '@ember-data/store/-private/utils/weak-cache';
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.getRecordData(this.#identifier).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,9 +466,9 @@ 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
- return members.every((identifier) => {
471
+ return localState.every((identifier) => {
439
472
  return this.store._instanceCache.recordIsLoaded(identifier, true) === true;
440
473
  });
441
474
  }
@@ -453,7 +486,7 @@ export default class HasManyReference {
453
486
  import Model, { hasMany } from '@ember-data/model';
454
487
 
455
488
  export default class PostModel extends Model {
456
- @hasMany({ async: true }) comments;
489
+ @hasMany('comment', { async: true, inverse: null }) comments;
457
490
  }
458
491
  ```
459
492
 
@@ -482,9 +515,9 @@ export default class HasManyReference {
482
515
  @return {ManyArray}
483
516
  */
484
517
  value() {
485
- const support: LegacySupport = (
486
- LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
487
- ).getWithError(this.#identifier);
518
+ const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
519
+ this.___identifier
520
+ )!;
488
521
 
489
522
  return this._isLoaded() ? support.getManyArray(this.key) : null;
490
523
  }
@@ -501,7 +534,7 @@ export default class HasManyReference {
501
534
  import Model, { hasMany } from '@ember-data/model';
502
535
 
503
536
  export default class PostModel extends Model {
504
- @hasMany({ async: true }) comments;
537
+ @hasMany('comment', { async: true, inverse: null }) comments;
505
538
  }
506
539
  ```
507
540
 
@@ -554,9 +587,9 @@ export default class HasManyReference {
554
587
  this has-many relationship.
555
588
  */
556
589
  async load(options?: FindOptions): Promise<ManyArray> {
557
- const support: LegacySupport = (
558
- LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
559
- ).getWithError(this.#identifier);
590
+ const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
591
+ this.___identifier
592
+ )!;
560
593
  return support.getHasMany(this.key, options) as Promise<ManyArray> | ManyArray; // this cast is necessary because typescript does not work properly with custom thenables;
561
594
  }
562
595
 
@@ -570,7 +603,7 @@ export default class HasManyReference {
570
603
  import Model, { hasMany } from '@ember-data/model';
571
604
 
572
605
  export default class PostModel extends Model {
573
- @hasMany({ async: true }) comments;
606
+ @hasMany('comment', { async: true, inverse: null }) comments;
574
607
  }
575
608
  ```
576
609
 
@@ -611,9 +644,9 @@ export default class HasManyReference {
611
644
  @return {Promise} a promise that resolves with the ManyArray in this has-many relationship.
612
645
  */
613
646
  reload(options?: FindOptions) {
614
- const support: LegacySupport = (
615
- LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
616
- ).getWithError(this.#identifier);
647
+ const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
648
+ this.___identifier
649
+ )!;
617
650
  return support.reloadHasMany(this.key, options);
618
651
  }
619
652
  }
@@ -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/index.js CHANGED
@@ -20,6 +20,8 @@ module.exports = Object.assign({}, addonBaseConfig, {
20
20
  '@ember/string',
21
21
  '@embroider/macros/es-compat',
22
22
 
23
+ '@ember/object/proxy',
24
+ '@ember/object/promise-proxy-mixin',
23
25
  '@ember/application',
24
26
  '@ember/array',
25
27
  '@ember/array/mutable',
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.6",
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.6",
26
+ "@ember-data/private-build-infra": "4.8.0-alpha.6",
27
+ "@ember-data/store": "4.8.0-alpha.6",
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.6",
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.16.0",
74
+ "node": "16.17.0",
71
75
  "yarn": "1.22.19"
72
76
  }
73
77
  }