@ember-data/model 4.8.0-alpha.4 → 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.
@@ -9,7 +9,7 @@ import {
9
9
  DEPRECATE_RELATIONSHIPS_WITHOUT_TYPE,
10
10
  } from '@ember-data/private-build-infra/deprecations';
11
11
 
12
- import { LEGACY_SUPPORT } from './model';
12
+ import { lookupLegacySupport } from './model';
13
13
  import { computedMacroWithOptionalParams } from './util';
14
14
 
15
15
  function normalizeType(type) {
@@ -205,7 +205,7 @@ function belongsTo(modelName, options) {
205
205
  if (this.isDestroying || this.isDestroyed) {
206
206
  return null;
207
207
  }
208
- const support = LEGACY_SUPPORT.lookup(this);
208
+ const support = lookupLegacySupport(this);
209
209
 
210
210
  if (DEBUG) {
211
211
  if (['currentState'].indexOf(key) !== -1) {
@@ -237,7 +237,7 @@ function belongsTo(modelName, options) {
237
237
  return support.getBelongsTo(key);
238
238
  },
239
239
  set(key, value) {
240
- const support = LEGACY_SUPPORT.lookup(this);
240
+ const support = lookupLegacySupport(this);
241
241
  if (DEBUG) {
242
242
  if (['currentState'].indexOf(key) !== -1) {
243
243
  throw new Error(
@@ -245,7 +245,7 @@ function belongsTo(modelName, options) {
245
245
  );
246
246
  }
247
247
  }
248
- this.store._backburner.join(() => {
248
+ this.store._join(() => {
249
249
  support.setDirtyBelongsTo(key, value);
250
250
  });
251
251
 
@@ -15,7 +15,7 @@ import {
15
15
  DEPRECATE_RELATIONSHIPS_WITHOUT_TYPE,
16
16
  } from '@ember-data/private-build-infra/deprecations';
17
17
 
18
- import { LEGACY_SUPPORT } from './model';
18
+ import { lookupLegacySupport } from './model';
19
19
  import { computedMacroWithOptionalParams } from './util';
20
20
 
21
21
  function normalizeType(type) {
@@ -249,7 +249,7 @@ function hasMany(type, options) {
249
249
  if (this.isDestroying || this.isDestroyed) {
250
250
  return A();
251
251
  }
252
- return LEGACY_SUPPORT.lookup(this).getHasMany(key);
252
+ return lookupLegacySupport(this).getHasMany(key);
253
253
  },
254
254
  set(key, records) {
255
255
  if (DEBUG) {
@@ -259,8 +259,8 @@ function hasMany(type, options) {
259
259
  );
260
260
  }
261
261
  }
262
- const support = LEGACY_SUPPORT.lookup(this);
263
- this.store._backburner.join(() => {
262
+ const support = lookupLegacySupport(this);
263
+ this.store._join(() => {
264
264
  support.setDirtyHasMany(key, records);
265
265
  });
266
266
 
@@ -5,9 +5,10 @@ import { importSync } from '@embroider/macros';
5
5
  import { all, resolve } from 'rsvp';
6
6
 
7
7
  import { HAS_RECORD_DATA_PACKAGE } from '@ember-data/private-build-infra';
8
- import type { BelongsToRelationship, ManyRelationship } from '@ember-data/record-data/-private';
9
8
  import type { UpgradedMeta } from '@ember-data/record-data/-private/graph/-edge-definition';
10
- import ImplicitRelationship from '@ember-data/record-data/-private/relationships/state/implicit';
9
+ import type { ImplicitRelationship } from '@ember-data/record-data/-private/graph/index';
10
+ import type BelongsToRelationship from '@ember-data/record-data/-private/relationships/state/belongs-to';
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, storeFor } from '@ember-data/store/-private';
13
14
  import { IdentifierCache } from '@ember-data/store/-private/caches/identifier-cache';
@@ -320,7 +321,8 @@ export class LegacySupport {
320
321
  const graphFor = (
321
322
  importSync('@ember-data/record-data/-private') as typeof import('@ember-data/record-data/-private')
322
323
  ).graphFor;
323
- const relationship = graphFor(this.store).get(this.identifier, name);
324
+ const graph = graphFor(this.store);
325
+ const relationship = graph.get(this.identifier, name);
324
326
 
325
327
  if (DEBUG && kind) {
326
328
  let modelName = this.identifier.type;
@@ -334,9 +336,15 @@ export class LegacySupport {
334
336
  let relationshipKind = relationship.definition.kind;
335
337
 
336
338
  if (relationshipKind === 'belongsTo') {
337
- reference = new BelongsToReference(this.store, this.identifier, relationship as BelongsToRelationship, name);
339
+ reference = new BelongsToReference(
340
+ this.store,
341
+ graph,
342
+ this.identifier,
343
+ relationship as BelongsToRelationship,
344
+ name
345
+ );
338
346
  } else if (relationshipKind === 'hasMany') {
339
- reference = new HasManyReference(this.store, this.identifier, relationship as ManyRelationship, name);
347
+ reference = new HasManyReference(this.store, graph, this.identifier, relationship as ManyRelationship, name);
340
348
  }
341
349
 
342
350
  this.references[name] = reference;
@@ -662,7 +670,7 @@ function isPromiseRecord(record: PromiseProxyRecord | RecordInstance): record is
662
670
  }
663
671
 
664
672
  function anyUnloaded(store: Store, relationship: ManyRelationship) {
665
- let state = relationship.currentState;
673
+ let state = relationship.localState;
666
674
  const cache = store._instanceCache;
667
675
  const unloaded = state.find((s) => {
668
676
  let isLoaded = cache.recordIsLoaded(s, true);
@@ -695,8 +703,8 @@ function areAllInverseRecordsLoaded(store: Store, resource: JsonApiRelationship)
695
703
 
696
704
  function isEmpty(store: Store, cache: IdentifierCache, resource: ResourceIdentifierObject): boolean {
697
705
  const identifier = cache.getOrCreateRecordIdentifier(resource);
698
- const recordData = store._instanceCache.peek({ identifier, bucket: 'recordData' });
699
- return !recordData || !!recordData.isEmpty?.(identifier);
706
+ const recordData = store._instanceCache.__instances.recordData.get(identifier);
707
+ return !recordData || recordData.isEmpty(identifier);
700
708
  }
701
709
 
702
710
  function isBelongsTo(
@@ -280,7 +280,7 @@ export default class ManyArray extends MutableArrayWithObject<StableRecordIdenti
280
280
  !objects || Array.isArray(objects) || EmberArray.detect(objects)
281
281
  );
282
282
  const { store, identifier } = this;
283
- store._backburner.join(() => {
283
+ store._join(() => {
284
284
  let identifiers: StableRecordIdentifier[];
285
285
  if (amt > 0) {
286
286
  identifiers = this.currentState.slice(idx, idx + amt);
@@ -23,7 +23,7 @@ import {
23
23
  DEPRECATE_SAVE_PROMISE_ACCESS,
24
24
  } from '@ember-data/private-build-infra/deprecations';
25
25
  import { recordIdentifierFor, storeFor } from '@ember-data/store';
26
- import { coerceId, deprecatedPromiseObject, recordDataFor, WeakCache } from '@ember-data/store/-private';
26
+ import { coerceId, deprecatedPromiseObject, recordDataFor } from '@ember-data/store/-private';
27
27
 
28
28
  import Errors from './errors';
29
29
  import { LegacySupport } from './legacy-relationships-support';
@@ -32,18 +32,21 @@ import RecordState, { peekTag, tagged } from './record-state';
32
32
  import { relationshipFromMeta } from './relationship-meta';
33
33
 
34
34
  const { changeProperties } = Ember;
35
- export const LEGACY_SUPPORT = new WeakCache(DEBUG ? 'legacy-relationships' : '');
36
- LEGACY_SUPPORT._generator = (record) => {
35
+ export const LEGACY_SUPPORT = new Map();
36
+
37
+ export function lookupLegacySupport(record) {
37
38
  const identifier = recordIdentifierFor(record);
38
39
  let support = LEGACY_SUPPORT.get(identifier);
39
40
 
40
41
  if (!support) {
41
42
  support = new LegacySupport(record);
42
43
  LEGACY_SUPPORT.set(identifier, support);
44
+ LEGACY_SUPPORT.set(record, support);
43
45
  }
44
46
 
45
47
  return support;
46
- };
48
+ }
49
+
47
50
  function findPossibleInverses(type, inverseType, name, relationshipsSoFar) {
48
51
  let possibleRelationships = relationshipsSoFar || [];
49
52
 
@@ -130,18 +133,18 @@ class Model extends EmberObject {
130
133
  }
131
134
  const createProps = options._createProps;
132
135
  const _secretInit = options._secretInit;
133
- delete options._createProps;
134
- delete options._secretInit;
136
+ options._createProps = null;
137
+ options._secretInit = null;
135
138
  super.init(options);
136
139
 
137
- _secretInit(this);
140
+ let identity = _secretInit.identifier;
141
+ _secretInit.cb(this, _secretInit.recordData, identity, _secretInit.store);
138
142
  this.___recordState = DEBUG ? new RecordState(this) : null;
139
143
 
140
144
  this.setProperties(createProps);
141
145
 
142
146
  let store = storeFor(this);
143
147
  let notifications = store._notificationManager;
144
- let identity = recordIdentifierFor(this);
145
148
 
146
149
  this.___private_notifications = notifications.subscribe(identity, (identifier, type, key) => {
147
150
  notifyChanges(identifier, type, key, this, store);
@@ -493,9 +496,8 @@ class Model extends EmberObject {
493
496
  }
494
497
  }
495
498
 
496
- // TODO just write a nice toString
497
- toStringExtension() {
498
- return this.id;
499
+ toString() {
500
+ return `<model::${this.constructor.modelName}:${this.id}>`;
499
501
  }
500
502
 
501
503
  /**
@@ -838,12 +840,14 @@ class Model extends EmberObject {
838
840
  rollbackAttributes() {
839
841
  const { currentState } = this;
840
842
  const { isNew } = currentState;
841
- recordDataFor(this).rollbackAttrs(recordIdentifierFor(this));
842
- this.errors.clear();
843
- currentState.cleanErrorRequests();
844
- if (isNew) {
845
- this.unloadRecord();
846
- }
843
+ storeFor(this)._join(() => {
844
+ recordDataFor(this).rollbackAttrs(recordIdentifierFor(this));
845
+ this.errors.clear();
846
+ currentState.cleanErrorRequests();
847
+ if (isNew) {
848
+ this.unloadRecord();
849
+ }
850
+ });
847
851
  }
848
852
 
849
853
  /**
@@ -1037,7 +1041,7 @@ class Model extends EmberObject {
1037
1041
  @return {BelongsToReference} reference for this relationship
1038
1042
  */
1039
1043
  belongsTo(name) {
1040
- return LEGACY_SUPPORT.lookup(this).referenceFor('belongsTo', name);
1044
+ return lookupLegacySupport(this).referenceFor('belongsTo', name);
1041
1045
  }
1042
1046
 
1043
1047
  /**
@@ -1100,7 +1104,7 @@ class Model extends EmberObject {
1100
1104
  @return {HasManyReference} reference for this relationship
1101
1105
  */
1102
1106
  hasMany(name) {
1103
- return LEGACY_SUPPORT.lookup(this).referenceFor('hasMany', name);
1107
+ return lookupLegacySupport(this).referenceFor('hasMany', name);
1104
1108
  }
1105
1109
 
1106
1110
  /**
@@ -105,7 +105,7 @@ export function tagged(_target, key, desc) {
105
105
 
106
106
  /**
107
107
  Historically EmberData managed a state machine
108
- for each record, the currentState for which
108
+ for each record, the localState for which
109
109
  was reflected onto Model.
110
110
 
111
111
  This implements the flags and stateName for backwards compat
@@ -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 { BelongsToRelationship } from '@ember-data/record-data/-private';
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
12
  import type { NotificationType } from '@ember-data/store/-private/managers/record-notification-manager';
12
- import type { DebugWeakCache } from '@ember-data/store/-private/utils/weak-cache';
13
13
  import type {
14
14
  LinkObject,
15
15
  Links,
@@ -54,6 +54,7 @@ export default class BelongsToReference {
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
  ___token!: object;
@@ -63,10 +64,12 @@ export default class BelongsToReference {
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;
@@ -394,9 +397,9 @@ export default class BelongsToReference {
394
397
  this.store
395
398
  );
396
399
 
397
- const { graph, identifier } = this.belongsToRelationship;
398
- this.store._backburner.join(() => {
399
- graph.push({
400
+ const { identifier } = this.belongsToRelationship;
401
+ this.store._join(() => {
402
+ this.graph.push({
400
403
  op: 'replaceRelatedRecord',
401
404
  record: identifier,
402
405
  field: this.key,
@@ -525,9 +528,9 @@ export default class BelongsToReference {
525
528
  @return {Promise} a promise that resolves with the record in this belongs-to relationship.
526
529
  */
527
530
  load(options?: Dict<unknown>) {
528
- const support: LegacySupport = (
529
- LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
530
- ).getWithError(this.___identifier);
531
+ const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
532
+ this.___identifier
533
+ )!;
531
534
  return support.getBelongsTo(this.key, options);
532
535
  }
533
536
 
@@ -582,9 +585,9 @@ export default class BelongsToReference {
582
585
  @return {Promise} a promise that resolves with the record in this belongs-to relationship after the reload has completed.
583
586
  */
584
587
  reload(options?: Dict<unknown>) {
585
- const support: LegacySupport = (
586
- LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
587
- ).getWithError(this.___identifier);
588
+ const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
589
+ this.___identifier
590
+ )!;
588
591
  return support.reloadBelongsTo(this.key, options).then(() => this.value());
589
592
  }
590
593
  }
@@ -7,12 +7,12 @@ import { resolve } from 'rsvp';
7
7
 
8
8
  import { ManyArray } from 'ember-data/-private';
9
9
 
10
- import type { ManyRelationship } from '@ember-data/record-data/-private';
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
15
  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
16
  import type {
17
17
  CollectionResourceDocument,
18
18
  CollectionResourceRelationship,
@@ -53,6 +53,7 @@ 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;
@@ -67,10 +68,12 @@ export default class HasManyReference {
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;
@@ -424,9 +427,9 @@ export default class HasManyReference {
424
427
  return recordIdentifierFor(record);
425
428
  });
426
429
 
427
- const { graph, identifier } = this.hasManyRelationship;
428
- store._backburner.join(() => {
429
- graph.push({
430
+ const { identifier } = this.hasManyRelationship;
431
+ store._join(() => {
432
+ this.graph.push({
430
433
  op: 'replaceRelatedRecords',
431
434
  record: identifier,
432
435
  field: this.key,
@@ -443,9 +446,9 @@ export default class HasManyReference {
443
446
  return false;
444
447
  }
445
448
 
446
- let members = this.hasManyRelationship.currentState;
449
+ let localState = this.hasManyRelationship.localState;
447
450
 
448
- return members.every((identifier) => {
451
+ return localState.every((identifier) => {
449
452
  return this.store._instanceCache.recordIsLoaded(identifier, true) === true;
450
453
  });
451
454
  }
@@ -492,9 +495,9 @@ export default class HasManyReference {
492
495
  @return {ManyArray}
493
496
  */
494
497
  value() {
495
- const support: LegacySupport = (
496
- LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
497
- ).getWithError(this.___identifier);
498
+ const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
499
+ this.___identifier
500
+ )!;
498
501
 
499
502
  return this._isLoaded() ? support.getManyArray(this.key) : null;
500
503
  }
@@ -564,9 +567,9 @@ export default class HasManyReference {
564
567
  this has-many relationship.
565
568
  */
566
569
  async load(options?: FindOptions): Promise<ManyArray> {
567
- const support: LegacySupport = (
568
- LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
569
- ).getWithError(this.___identifier);
570
+ const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
571
+ this.___identifier
572
+ )!;
570
573
  return support.getHasMany(this.key, options) as Promise<ManyArray> | ManyArray; // this cast is necessary because typescript does not work properly with custom thenables;
571
574
  }
572
575
 
@@ -621,9 +624,9 @@ export default class HasManyReference {
621
624
  @return {Promise} a promise that resolves with the ManyArray in this has-many relationship.
622
625
  */
623
626
  reload(options?: FindOptions) {
624
- const support: LegacySupport = (
625
- LEGACY_SUPPORT as DebugWeakCache<StableRecordIdentifier, LegacySupport>
626
- ).getWithError(this.___identifier);
627
+ const support: LegacySupport = (LEGACY_SUPPORT as Map<StableRecordIdentifier, LegacySupport>).get(
628
+ this.___identifier
629
+ )!;
627
630
  return support.reloadHasMany(this.key, options);
628
631
  }
629
632
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ember-data/model",
3
- "version": "4.8.0-alpha.4",
3
+ "version": "4.8.0-alpha.5",
4
4
  "description": "A presentation layer for apps built with @ember-data/store",
5
5
  "keywords": [
6
6
  "ember-addon"
@@ -22,9 +22,9 @@
22
22
  "test:node": "mocha"
23
23
  },
24
24
  "dependencies": {
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",
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",
28
28
  "@ember/edition-utils": "^1.2.0",
29
29
  "@ember/string": "^3.0.0",
30
30
  "@embroider/macros": "^1.8.3",
@@ -38,7 +38,7 @@
38
38
  "inflection": "~1.13.2"
39
39
  },
40
40
  "devDependencies": {
41
- "@ember-data/unpublished-test-infra": "4.8.0-alpha.4",
41
+ "@ember-data/unpublished-test-infra": "4.8.0-alpha.5",
42
42
  "@ember/optional-features": "^2.0.0",
43
43
  "@ember/test-helpers": "~2.7.0",
44
44
  "broccoli-asset-rev": "^3.0.0",
@@ -71,7 +71,7 @@
71
71
  "configPath": "tests/dummy/config"
72
72
  },
73
73
  "volta": {
74
- "node": "16.16.0",
74
+ "node": "16.17.0",
75
75
  "yarn": "1.22.19"
76
76
  }
77
77
  }