From 5a205b864934f31a5079608e7aef8d6fc71fd310 Mon Sep 17 00:00:00 2001 From: Gaurav Munjal Date: Fri, 29 Nov 2019 22:11:55 -0500 Subject: [PATCH] [CHORE] Move PromiseBelongsTo, PromiseManyArray and ManyArray to model package (#6822) * [CHORE] Move PromiseBelongsTo, PromiseManyArray and ManyArray to model package * fixes * reduce inter-dependency by moving proxyToContent * cleanup --- packages/-ember-data/addon/-private/index.js | 3 +- .../node-tests/fixtures/expected.js | 2 +- packages/model/addon/-private/index.ts | 3 + .../addon/-private/system/many-array.js | 10 +-- .../-private/system/promise-belongs-to.js | 40 ++++++++++ .../-private/system/promise-many-array.js | 56 +++++++++++++ packages/store/addon/-private/index.ts | 3 +- .../-private/system/model/internal-model.ts | 42 +++++++--- .../-private/system/normalize-model-name.js | 4 +- .../addon/-private/system/promise-proxies.js | 78 +------------------ 10 files changed, 141 insertions(+), 100 deletions(-) rename packages/{store => model}/addon/-private/system/many-array.js (95%) create mode 100644 packages/model/addon/-private/system/promise-belongs-to.js create mode 100644 packages/model/addon/-private/system/promise-many-array.js diff --git a/packages/-ember-data/addon/-private/index.js b/packages/-ember-data/addon/-private/index.js index 664326f0cd4..1907debd956 100644 --- a/packages/-ember-data/addon/-private/index.js +++ b/packages/-ember-data/addon/-private/index.js @@ -9,9 +9,7 @@ export { Snapshot } from '@ember-data/store/-private'; export { AdapterPopulatedRecordArray, InternalModel, - ManyArray, PromiseArray, - PromiseManyArray, PromiseObject, RecordArray, RecordArrayManager, @@ -20,4 +18,5 @@ export { normalizeModelName, coerceId, } from '@ember-data/store/-private'; +export { ManyArray, PromiseManyArray } from '@ember-data/model/-private'; export { RecordData, Relationship } from '@ember-data/record-data/-private'; diff --git a/packages/-ember-data/node-tests/fixtures/expected.js b/packages/-ember-data/node-tests/fixtures/expected.js index d7c0eedf67f..4e6e6cca1f3 100644 --- a/packages/-ember-data/node-tests/fixtures/expected.js +++ b/packages/-ember-data/node-tests/fixtures/expected.js @@ -258,6 +258,7 @@ module.exports = { '(public) @ember-data/serializer Serializer#store', '(public) @ember-data/serializer Transform#deserialize', '(public) @ember-data/serializer Transform#serialize', + '(public) @ember-data/store @ember-data/store#normalizeModelName', '(public) @ember-data/store BelongsToReference#id', '(public) @ember-data/store BelongsToReference#load', '(public) @ember-data/store BelongsToReference#push', @@ -296,7 +297,6 @@ module.exports = { '(public) @ember-data/store RecordArrayManager#createAdapterPopulatedRecordArray', '(public) @ember-data/store RecordArrayManager#createRecordArray', '(public) @ember-data/store RecordArrayManager#liveRecordArrayFor', - '(public) @ember-data/store RecordArrayManager#normalizeModelName', '(public) @ember-data/store RecordArrayManager#unregisterRecordArray', '(public) @ember-data/store RecordReference#id', '(public) @ember-data/store RecordReference#load', diff --git a/packages/model/addon/-private/index.ts b/packages/model/addon/-private/index.ts index 5dfe41eede7..7f48d042fb5 100644 --- a/packages/model/addon/-private/index.ts +++ b/packages/model/addon/-private/index.ts @@ -4,4 +4,7 @@ export { default as hasMany } from './has-many'; export { default as Model } from './model'; export { default as Errors } from './errors'; +export { default as ManyArray } from './system/many-array'; +export { default as PromiseBelongsTo } from './system/promise-belongs-to'; +export { default as PromiseManyArray } from './system/promise-many-array'; export { default as _modelForMixin } from './system/model-for-mixin'; diff --git a/packages/store/addon/-private/system/many-array.js b/packages/model/addon/-private/system/many-array.js similarity index 95% rename from packages/store/addon/-private/system/many-array.js rename to packages/model/addon/-private/system/many-array.js index 6e7c3d22f73..d3914e2795c 100644 --- a/packages/store/addon/-private/system/many-array.js +++ b/packages/model/addon/-private/system/many-array.js @@ -4,15 +4,11 @@ import { all } from 'rsvp'; //import Evented from '@ember/object/evented'; -import DeprecatedEvent from './deprecated-evented'; import MutableArray from '@ember/array/mutable'; import EmberArray from '@ember/array'; import EmberObject, { get } from '@ember/object'; import { assert } from '@ember/debug'; -import { PromiseArray } from './promise-proxies'; -import { _objectIsAlive } from './store/common'; -import diffArray from './diff-array'; -import recordDataFor from './record-data-for'; +import { DeprecatedEvented, PromiseArray, diffArray, _objectIsAlive, recordDataFor } from '@ember-data/store/-private'; import { CUSTOM_MODEL_CLASS, FULL_LINKS_ON_RELATIONSHIPS } from '@ember-data/canary-features'; /** @@ -55,9 +51,9 @@ import { CUSTOM_MODEL_CLASS, FULL_LINKS_ON_RELATIONSHIPS } from '@ember-data/can @class ManyArray @extends EmberObject - @uses Ember.MutableArray, EmberData.DeprecatedEvent + @uses Ember.MutableArray, DeprecatedEvented */ -export default EmberObject.extend(MutableArray, DeprecatedEvent, { +export default EmberObject.extend(MutableArray, DeprecatedEvented, { // here to make TS happy _inverseIsAsync: false, isLoaded: false, diff --git a/packages/model/addon/-private/system/promise-belongs-to.js b/packages/model/addon/-private/system/promise-belongs-to.js new file mode 100644 index 00000000000..0a59a64e09d --- /dev/null +++ b/packages/model/addon/-private/system/promise-belongs-to.js @@ -0,0 +1,40 @@ +import { computed } from '@ember/object'; +import { assert } from '@ember/debug'; +import { PromiseObject } from '@ember-data/store/-private'; + +/** + @module @ember-data/model + */ + +/** + A PromiseBelongsTo is a PromiseObject that also proxies certain method calls + to the underlying belongsTo model. + Right now we proxy: + + * `reload()` + + @class PromiseBelongsTo + @extends PromiseObject + @private +*/ +const PromiseBelongsTo = PromiseObject.extend({ + // we don't proxy meta because we would need to proxy it to the relationship state container + // however, meta on relationships does not trigger change notifications. + // if you need relationship meta, you should do `record.belongsTo(relationshipName).meta()` + meta: computed(function() { + assert( + 'You attempted to access meta on the promise for the async belongsTo relationship ' + + `${this.get('_belongsToState').modelName}:${this.get('_belongsToState').key}'.` + + '\nUse `record.belongsTo(relationshipName).meta()` instead.', + false + ); + }), + + reload(options) { + assert('You are trying to reload an async belongsTo before it has been created', this.get('content') !== undefined); + let { key, store, originatingInternalModel } = this._belongsToState; + return store.reloadBelongsTo(this, originatingInternalModel, key, options).then(() => this); + }, +}); + +export default PromiseBelongsTo; diff --git a/packages/model/addon/-private/system/promise-many-array.js b/packages/model/addon/-private/system/promise-many-array.js new file mode 100644 index 00000000000..541370c8ade --- /dev/null +++ b/packages/model/addon/-private/system/promise-many-array.js @@ -0,0 +1,56 @@ +import { get } from '@ember/object'; +import { reads } from '@ember/object/computed'; +import { Promise } from 'rsvp'; +import { assert } from '@ember/debug'; +import { FULL_LINKS_ON_RELATIONSHIPS } from '@ember-data/canary-features'; +import { PromiseArray } from '@ember-data/store/-private'; + +/** + @module @ember-data/model + */ + +/** + A PromiseManyArray is a PromiseArray that also proxies certain method calls + to the underlying manyArray. + Right now we proxy: + + * `reload()` + * `createRecord()` + * `on()` + * `one()` + * `trigger()` + * `off()` + * `has()` + + @class PromiseManyArray + @extends Ember.ArrayProxy + @private +*/ +const PromiseManyArray = PromiseArray.extend({ + links: FULL_LINKS_ON_RELATIONSHIPS ? reads('content.links') : undefined, + reload(options) { + assert('You are trying to reload an async manyArray before it has been created', get(this, 'content')); + this.set('promise', this.get('content').reload(options)); + return this; + }, + createRecord: proxyToContent('createRecord'), + on: proxyToContent('on'), + one: proxyToContent('one'), + trigger: proxyToContent('trigger'), + off: proxyToContent('off'), + has: proxyToContent('has'), +}); + +export default PromiseManyArray; + +export function promiseManyArray(promise, label) { + return PromiseManyArray.create({ + promise: Promise.resolve(promise, label), + }); +} + +function proxyToContent(method) { + return function() { + return get(this, 'content')[method](...arguments); + }; +} diff --git a/packages/store/addon/-private/index.ts b/packages/store/addon/-private/index.ts index 9c144a27161..30a992d02eb 100644 --- a/packages/store/addon/-private/index.ts +++ b/packages/store/addon/-private/index.ts @@ -24,11 +24,10 @@ export { errorsHashToArray, errorsArrayToHash } from './system/errors-utils'; export { default as RootState } from './system/model/states'; export { default as InternalModel } from './system/model/internal-model'; -export { PromiseArray, PromiseObject, PromiseManyArray } from './system/promise-proxies'; +export { PromiseArray, PromiseObject } from './system/promise-proxies'; export { RecordArray, AdapterPopulatedRecordArray } from './system/record-arrays'; -export { default as ManyArray } from './system/many-array'; export { default as RecordArrayManager } from './system/record-array-manager'; // // Used by tests diff --git a/packages/store/addon/-private/system/model/internal-model.ts b/packages/store/addon/-private/system/model/internal-model.ts index b34a96a6a8f..b1ffd39f3ba 100644 --- a/packages/store/addon/-private/system/model/internal-model.ts +++ b/packages/store/addon/-private/system/model/internal-model.ts @@ -10,11 +10,10 @@ import { DEBUG } from '@glimmer/env'; import { assert, inspect } from '@ember/debug'; import RootState from './states'; import Snapshot from '../snapshot'; -import ManyArray from '../many-array'; -import { PromiseBelongsTo, PromiseManyArray } from '../promise-proxies'; import Store from '../ds-model-store'; import { errorsHashToArray } from '../errors-utils'; import RecordArray from '../record-arrays/record-array'; +// import { PromiseArray } from '../promise-proxies'; import { RecordReference, BelongsToReference, HasManyReference } from '../references'; import { RecordData } from '../../ts-interfaces/record-data'; @@ -35,12 +34,22 @@ import { internalModelFactoryFor, setRecordIdentifier } from '../store/internal- import CoreStore from '../core-store'; import coerceId from '../coerce-id'; import recordDataFor from '../record-data-for'; +import { HAS_MODEL_PACKAGE } from '@ember-data/private-build-infra'; type DefaultRecordData = import('@ember-data/record-data/-private').RecordData; type RecordArray = InstanceType; type RelationshipRecordData = import('@ember-data/record-data/-private/ts-interfaces/relationship-record-data').RelationshipRecordData; type Relationships = import('@ember-data/record-data/-private/relationships/state/create').default; +// move to TS hacks module that we can delete when this is no longer a necessary recast +type ManyArray = InstanceType; +type PromiseBelongsTo = InstanceType; +type PromiseManyArray = InstanceType; + +/** + @module @ember-data/store +*/ + // once the presentation logic is moved into the Model package we can make // eliminate these lossy and redundant helpers function relationshipsFor(instance: InternalModel): Relationships { @@ -55,14 +64,24 @@ function relationshipStateFor(instance: InternalModel, propertyName: string) { const { hasOwnProperty } = Object.prototype; -/** - @module @ember-data/store -*/ - -// move to TS hacks module that we can delete when this is no longer a necessary recast -type ManyArray = InstanceType; -type PromiseBelongsTo = InstanceType; -type PromiseManyArray = InstanceType; +let ManyArray: ManyArray; +let PromiseBelongsTo: PromiseBelongsTo; +let PromiseManyArray: PromiseManyArray; + +let _found = false; +let _getModelPackage: () => boolean; +if (HAS_MODEL_PACKAGE) { + _getModelPackage = function() { + if (!_found) { + let modelPackage = require('@ember-data/model/-private'); + ({ ManyArray, PromiseBelongsTo, PromiseManyArray } = modelPackage); + if (ManyArray && PromiseBelongsTo && PromiseManyArray) { + _found = true; + } + } + return _found; + }; +} // TODO this should be integrated with the code removal so we can use it together with the if condition // and not alongside it @@ -149,6 +168,9 @@ export default class InternalModel { error: any; constructor(public store: CoreStore | Store, public identifier: StableRecordIdentifier) { + if (HAS_MODEL_PACKAGE) { + _getModelPackage(); + } this._id = identifier.id; this.modelName = identifier.type; this.clientId = identifier.lid; diff --git a/packages/store/addon/-private/system/normalize-model-name.js b/packages/store/addon/-private/system/normalize-model-name.js index ffe6df9e05a..0a1ccc06337 100644 --- a/packages/store/addon/-private/system/normalize-model-name.js +++ b/packages/store/addon/-private/system/normalize-model-name.js @@ -11,8 +11,8 @@ import { dasherize } from '@ember/string'; This method normalizes a modelName into the format Ember Data uses internally. - @method normalizeModelName - @public + @function normalizeModelName + @for @ember-data/store @param {String} modelName @return {String} normalizedModelName */ diff --git a/packages/store/addon/-private/system/promise-proxies.js b/packages/store/addon/-private/system/promise-proxies.js index a60933612f1..5ab7ccd2ef1 100644 --- a/packages/store/addon/-private/system/promise-proxies.js +++ b/packages/store/addon/-private/system/promise-proxies.js @@ -1,17 +1,14 @@ import ObjectProxy from '@ember/object/proxy'; import PromiseProxyMixin from '@ember/object/promise-proxy-mixin'; import ArrayProxy from '@ember/array/proxy'; -import { get, computed } from '@ember/object'; import { reads } from '@ember/object/computed'; import { Promise } from 'rsvp'; -import { assert } from '@ember/debug'; -import { FULL_LINKS_ON_RELATIONSHIPS } from '@ember-data/canary-features'; /** @module @ember-data/store */ -/* +/** A `PromiseArray` is an object that acts like both an `Ember.Array` and a promise. When the promise is resolved the resulting value will be set to the `PromiseArray`'s `content` property. This makes @@ -43,7 +40,7 @@ export const PromiseArray = ArrayProxy.extend(PromiseProxyMixin, { meta: reads('content.meta'), }); -/* +/** A `PromiseObject` is an object that acts like both an `EmberObject` and a promise. When the promise is resolved, then the resulting value will be set to the `PromiseObject`'s `content` property. This makes @@ -84,74 +81,3 @@ export function promiseArray(promise, label) { promise: Promise.resolve(promise, label), }); } - -export const PromiseBelongsTo = PromiseObject.extend({ - // we don't proxy meta because we would need to proxy it to the relationship state container - // however, meta on relationships does not trigger change notifications. - // if you need relationship meta, you should do `record.belongsTo(relationshipName).meta()` - meta: computed(function() { - assert( - 'You attempted to access meta on the promise for the async belongsTo relationship ' + - `${this.get('_belongsToState').modelName}:${this.get('_belongsToState').key}'.` + - '\nUse `record.belongsTo(relationshipName).meta()` instead.', - false - ); - }), - - reload(options) { - assert('You are trying to reload an async belongsTo before it has been created', this.get('content') !== undefined); - let { key, store, originatingInternalModel } = this._belongsToState; - - return store.reloadBelongsTo(this, originatingInternalModel, key, options).then(() => this); - }, -}); - -export function proxyToContent(method) { - return function() { - return get(this, 'content')[method](...arguments); - }; -} - -/* - A PromiseManyArray is a PromiseArray that also proxies certain method calls - to the underlying manyArray. - Right now we proxy: - - * `reload()` - * `createRecord()` - * `on()` - * `one()` - * `trigger()` - * `off()` - * `has()` - - @class PromiseManyArray - @extends Ember.ArrayProxy -*/ -export const PromiseManyArray = PromiseArray.extend({ - links: FULL_LINKS_ON_RELATIONSHIPS ? reads('content.links') : undefined, - - reload(options) { - assert('You are trying to reload an async manyArray before it has been created', get(this, 'content')); - this.set('promise', this.get('content').reload(options)); - return this; - }, - - createRecord: proxyToContent('createRecord'), - - on: proxyToContent('on'), - - one: proxyToContent('one'), - - trigger: proxyToContent('trigger'), - - off: proxyToContent('off'), - - has: proxyToContent('has'), -}); - -export function promiseManyArray(promise, label) { - return PromiseManyArray.create({ - promise: Promise.resolve(promise, label), - }); -}