Skip to content

Commit

Permalink
[CHORE]: Extract internalModel access to identifiers for Relationships (
Browse files Browse the repository at this point in the history
  • Loading branch information
snewcomer authored Oct 30, 2020
1 parent 96f871a commit 1428e26
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 47 deletions.
1 change: 1 addition & 0 deletions packages/-ember-data/node-tests/fixtures/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ module.exports = {
'(public) @ember-data/store RecordArrayManager#liveRecordArrayFor',
'(public) @ember-data/store RecordArrayManager#unregisterRecordArray',
'(public) @ember-data/store RecordReference#id',
'(public) @ember-data/store RecordReference#identifier',
'(public) @ember-data/store RecordReference#load',
'(public) @ember-data/store RecordReference#push',
'(public) @ember-data/store RecordReference#reload',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ module('integration/references/belongs-to', function(hooks) {
var personReference = store.getReference('person', 1);
var familyReference = person.belongsTo('family');

assert.ok(personReference);
assert.equal(familyReference.parent, personReference);
assert.ok(personReference, 'person reference is present');
assert.deepEqual(familyReference.parent, personReference, 'parent reference on BelongsToReference');
});

test('BelongsToReference#meta() returns the most recent meta for the relationship', async function(assert) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ module('integration/references/has-many', function(hooks) {
var familyReference = store.getReference('family', 1);
var personsReference = family.hasMany('persons');

assert.ok(familyReference);
assert.equal(personsReference.parent, familyReference);
assert.ok(familyReference, 'person reference is present');
assert.deepEqual(personsReference.parent, familyReference, 'parent reference on HasManyReferencee');
});

test('HasManyReference#meta() returns the most recent meta for the relationship', function(assert) {
Expand Down
18 changes: 17 additions & 1 deletion packages/store/addon/-private/system/core-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import { promiseArray, promiseObject } from './promise-proxies';
import RecordArrayManager from './record-array-manager';
import recordDataFor from './record-data-for';
import NotificationManager from './record-notification-manager';
import { RecordReference } from './references';
import { RequestPromise } from './request-cache';
import { _bind, _guard, _objectIsAlive, guardDestroyedStore } from './store/common';
import { _find, _findAll, _findBelongsTo, _findHasMany, _findMany, _query, _queryRecord } from './store/finders';
Expand Down Expand Up @@ -113,6 +114,8 @@ type PendingSaveItem = {

let _Model;

const RECORD_REFERENCES = new WeakMap<StableRecordIdentifier, RecordReference>();

function getModel() {
if (HAS_MODEL_PACKAGE) {
_Model = _Model || require('@ember-data/model').default;
Expand Down Expand Up @@ -1484,7 +1487,20 @@ abstract class CoreStore extends Service {
const normalizedId = ensureStringId(id);
const resource = constructResource(type, normalizedId);

return internalModelFactoryFor(this).lookup(resource).recordReference;
if (RECORD_ARRAY_MANAGER_IDENTIFIERS) {
let identifier: StableRecordIdentifier = identifierCacheFor(this).getOrCreateRecordIdentifier(resource);
if (identifier) {
if (RECORD_REFERENCES.has(identifier)) {
return RECORD_REFERENCES.get(identifier);
}

let reference = new RecordReference(this, identifier);
RECORD_REFERENCES.set(identifier, reference);
return reference;
}
} else {
return internalModelFactoryFor(this).lookup(resource).recordReference;
}
}

/**
Expand Down
21 changes: 16 additions & 5 deletions packages/store/addon/-private/system/model/internal-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,11 @@ export default class InternalModel {

get recordReference() {
if (this._recordReference === null) {
this._recordReference = new RecordReference(this.store, this);
if (RECORD_ARRAY_MANAGER_IDENTIFIERS) {
this._recordReference = new RecordReference(this.store, this.identifier);
} else {
this._recordReference = new RecordReference(this.store, this);
}
}
return this._recordReference;
}
Expand Down Expand Up @@ -1566,10 +1570,17 @@ export default class InternalModel {
}

let relationshipKind = relationship.relationshipMeta.kind;
let identifierOrInternalModel;
if (RECORD_ARRAY_MANAGER_IDENTIFIERS) {
identifierOrInternalModel = this.identifier;
} else {
identifierOrInternalModel = this;
}

if (relationshipKind === 'belongsTo') {
reference = new BelongsToReference(this.store, this, relationship, name);
reference = new BelongsToReference(this.store, identifierOrInternalModel, relationship, name);
} else if (relationshipKind === 'hasMany') {
reference = new HasManyReference(this.store, this, relationship, name);
reference = new HasManyReference(this.store, identifierOrInternalModel, relationship, name);
}

this.references[name] = reference;
Expand All @@ -1580,8 +1591,8 @@ export default class InternalModel {
}

if (RECORD_ARRAY_MANAGER_IDENTIFIERS) {
// in production code, this is only accessed in `record-array-manager`
// if LEGACY_COMPAT is also on
// in production code, this is only accesssed in `record-array-manager`
// if REMOVE_RECORD_ARRAY_MANAGER_LEGACY_COMPAT is also false
if (!REMOVE_RECORD_ARRAY_MANAGER_LEGACY_COMPAT) {
Object.defineProperty(InternalModel.prototype, '_recordArrays', {
get() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ import { dasherize } from '@ember/string';
@param {String} modelName
@return {String} normalizedModelName
*/
export default function normalizeModelName(modelName) {
export default function normalizeModelName(modelName: string): string {
return dasherize(modelName);
}
40 changes: 28 additions & 12 deletions packages/store/addon/-private/system/references/belongs-to.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import { deprecate } from '@ember/debug';

import { resolve } from 'rsvp';

import { RECORD_ARRAY_MANAGER_IDENTIFIERS } from '@ember-data/canary-features';
import { DEPRECATE_BELONGS_TO_REFERENCE_PUSH } from '@ember-data/private-build-infra/deprecations';
import { assertPolymorphicType } from '@ember-data/store/-debug';

import recordDataFor from '../record-data-for';
import { peekRecordIdentifier } from '../store/internal-model-factory';
import Reference, { INTERNAL_MODELS } from './reference';
import { internalModelFactoryFor, peekRecordIdentifier } from '../store/internal-model-factory';
import Reference, { internalModelForReference } from './reference';

/**
@module @ember-data/store
Expand All @@ -22,13 +23,18 @@ import Reference, { INTERNAL_MODELS } from './reference';
@extends Reference
*/
export default class BelongsToReference extends Reference {
constructor(store, parentInternalModel, belongsToRelationship, key) {
super(store, parentInternalModel);
constructor(store, parentIMOrIdentifier, belongsToRelationship, key) {
super(store, parentIMOrIdentifier);
this.key = key;
this.belongsToRelationship = belongsToRelationship;
this.type = belongsToRelationship.relationshipMeta.type;
this.parent = parentInternalModel.recordReference;
this.parentInternalModel = parentInternalModel;
if (RECORD_ARRAY_MANAGER_IDENTIFIERS) {
this.parent = internalModelFactoryFor(store).peek(parentIMOrIdentifier).recordReference;
this.parentIdentifier = parentIMOrIdentifier;
} else {
this.parent = parentIMOrIdentifier.recordReference;
this.parentInternalModel = parentIMOrIdentifier;
}

// TODO inverse
}
Expand Down Expand Up @@ -82,7 +88,7 @@ export default class BelongsToReference extends Reference {
}

_resource() {
return INTERNAL_MODELS.get(this)?._recordData.getBelongsTo(this.key);
return this.recordData.getBelongsTo(this.key);
}

/**
Expand Down Expand Up @@ -146,7 +152,7 @@ export default class BelongsToReference extends Reference {
}

assertPolymorphicType(
INTERNAL_MODELS.get(this),
internalModelForReference(this),
this.belongsToRelationship.relationshipMeta,
record._internalModel,
this.store
Expand Down Expand Up @@ -209,10 +215,9 @@ export default class BelongsToReference extends Reference {
@return {Model} the record in this relationship
*/
value() {
let store = this.parentInternalModel.store;
let resource = this._resource();
if (resource && resource.data) {
let inverseInternalModel = store._internalModelForResource(resource.data);
let inverseInternalModel = this.store._internalModelForResource(resource.data);
if (inverseInternalModel && inverseInternalModel.isLoaded()) {
return inverseInternalModel.getRecord();
}
Expand Down Expand Up @@ -283,7 +288,12 @@ export default class BelongsToReference extends Reference {
@return {Promise} a promise that resolves with the record in this belongs-to relationship.
*/
load(options) {
return this.parentInternalModel.getBelongsTo(this.key, options);
if (RECORD_ARRAY_MANAGER_IDENTIFIERS) {
let parentInternalModel = internalModelFactoryFor(this.store).peek(this.parentIdentifier);
return parentInternalModel.getBelongsTo(this.key, options);
} else {
return this.parentInternalModel.getBelongsTo(this.key, options);
}
}

/**
Expand Down Expand Up @@ -336,7 +346,13 @@ export default class BelongsToReference extends Reference {
@return {Promise} a promise that resolves with the record in this belongs-to relationship after the reload has completed.
*/
reload(options) {
return this.parentInternalModel.reloadBelongsTo(this.key, options).then(internalModel => {
let parentInternalModel;
if (RECORD_ARRAY_MANAGER_IDENTIFIERS) {
parentInternalModel = internalModelFactoryFor(this.store).peek(this.parentIdentifier);
} else {
parentInternalModel = this.parentInternalModel;
}
return parentInternalModel.reloadBelongsTo(this.key, options).then(internalModel => {
return this.value();
});
}
Expand Down
29 changes: 17 additions & 12 deletions packages/store/addon/-private/system/references/has-many.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { DEBUG } from '@glimmer/env';

import { resolve } from 'rsvp';

import { RECORD_ARRAY_MANAGER_IDENTIFIERS } from '@ember-data/canary-features';
import { assertPolymorphicType } from '@ember-data/store/-debug';

import recordDataFor from '../record-data-for';
import Reference, { INTERNAL_MODELS } from './reference';
import { internalModelFactoryFor } from '../store/internal-model-factory';
import Reference, { internalModelForReference } from './reference';

/**
@module @ember-data/store
Expand All @@ -19,19 +21,23 @@ import Reference, { INTERNAL_MODELS } from './reference';
@extends Reference
*/
export default class HasManyReference extends Reference {
constructor(store, parentInternalModel, hasManyRelationship, key) {
super(store, parentInternalModel);
constructor(store, parentIMOrIdentifier, hasManyRelationship, key) {
super(store, parentIMOrIdentifier);
this.key = key;
this.hasManyRelationship = hasManyRelationship;
this.type = hasManyRelationship.relationshipMeta.type;
this.parent = parentInternalModel.recordReference;
this.parentInternalModel = parentInternalModel;

if (RECORD_ARRAY_MANAGER_IDENTIFIERS) {
this.parent = internalModelFactoryFor(store).peek(parentIMOrIdentifier).recordReference;
} else {
this.parent = parentIMOrIdentifier.recordReference;
}

// TODO inverse
}

_resource() {
return INTERNAL_MODELS.get(this)?._recordData.getHasMany(this.key);
return this.recordData.getHasMany(this.key);
}

/**
Expand Down Expand Up @@ -181,7 +187,7 @@ export default class HasManyReference extends Reference {
array = payload.data;
}

let internalModel = INTERNAL_MODELS.get(this);
let internalModel = internalModelForReference(this);

let internalModels = array.map(obj => {
let record = this.store.push(obj);
Expand Down Expand Up @@ -211,8 +217,7 @@ export default class HasManyReference extends Reference {

//TODO Igor cleanup
return members.every(recordData => {
let store = this.parentInternalModel.store;
let internalModel = store._internalModelForResource(recordData.getResourceIdentifier());
let internalModel = this.store._internalModelForResource(recordData.getResourceIdentifier());
return internalModel.isLoaded() === true;
});
}
Expand Down Expand Up @@ -258,7 +263,7 @@ export default class HasManyReference extends Reference {
@return {ManyArray}
*/
value() {
let internalModel = INTERNAL_MODELS.get(this);
let internalModel = internalModelForReference(this);
if (this._isLoaded()) {
return internalModel.getManyArray(this.key);
}
Expand Down Expand Up @@ -330,7 +335,7 @@ export default class HasManyReference extends Reference {
this has-many relationship.
*/
load(options) {
let internalModel = INTERNAL_MODELS.get(this);
let internalModel = internalModelForReference(this);
return internalModel.getHasMany(this.key, options);
}

Expand Down Expand Up @@ -384,7 +389,7 @@ export default class HasManyReference extends Reference {
@return {Promise} a promise that resolves with the ManyArray in this has-many relationship.
*/
reload(options) {
let internalModel = INTERNAL_MODELS.get(this);
let internalModel = internalModelForReference(this);
return internalModel.reloadHasMany(this.key, options);
}
}
49 changes: 43 additions & 6 deletions packages/store/addon/-private/system/references/record.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import RSVP, { resolve } from 'rsvp';

import Reference, { INTERNAL_MODELS } from './reference';
import { RECORD_ARRAY_MANAGER_IDENTIFIERS } from '@ember-data/canary-features';

import Reference, { internalModelForReference, REFERENCE_CACHE } from './reference';

type SingleResourceDocument = import('../../ts-interfaces/ember-data-json-api').SingleResourceDocument;
type RecordInstance = import('../../ts-interfaces/record-instance').RecordInstance;
type StableRecordIdentifier = import('../../ts-interfaces/identifier').StableRecordIdentifier;

/**
@module @ember-data/store
Expand All @@ -17,12 +20,25 @@ type RecordInstance = import('../../ts-interfaces/record-instance').RecordInstan
@extends Reference
*/
export default class RecordReference extends Reference {
public get type() {
return INTERNAL_MODELS.get(this)!.modelName;
public get type(): string {
if (RECORD_ARRAY_MANAGER_IDENTIFIERS) {
return this.identifier().type;
} else {
return internalModelForReference(this)!.modelName;
}
}

private get _id() {
return INTERNAL_MODELS.get(this)!.id;
private get _id(): string | null {
if (RECORD_ARRAY_MANAGER_IDENTIFIERS) {
let identifier = this.identifier();
if (identifier) {
return identifier.id;
}

return null;
} else {
return internalModelForReference(this)!.id;
}
}

/**
Expand All @@ -46,6 +62,27 @@ export default class RecordReference extends Reference {
return this._id;
}

/**
The `identifier` of the record that this reference refers to.
Together, the `type` and `id` properties form a composite key for
the identity map.
Example
```javascript
let userRef = store.getReference('user', 1);
userRef.identifier(); // '1'
```
@method identifier
@return {String} The identifier of the record.
*/
identifier(): StableRecordIdentifier {
return REFERENCE_CACHE.get(this) as StableRecordIdentifier;
}

/**
How the reference will be looked up when it is loaded. Currently
this always returns `identity` to signify that a record will be
Expand Down Expand Up @@ -128,7 +165,7 @@ export default class RecordReference extends Reference {
*/
value(): RecordInstance | null {
if (this._id !== null) {
let internalModel = INTERNAL_MODELS.get(this);
let internalModel = internalModelForReference(this);
if (internalModel && internalModel.isLoaded()) {
return internalModel.getRecord();
}
Expand Down
Loading

0 comments on commit 1428e26

Please sign in to comment.