Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: convert store to ts #6239

Merged
merged 3 commits into from
Jul 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 7 additions & 31 deletions packages/store/addon/-private/system/model/internal-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import { RECORD_DATA_ERRORS, RECORD_DATA_STATE } from '@ember-data/canary-featur

// move to TS hacks module that we can delete when this is no longer a necessary recast
type ManyArray = InstanceType<typeof ManyArray>;
type Store = InstanceType<typeof Store>;
type PromiseBelongsTo = InstanceType<typeof PromiseBelongsTo>;
type PromiseManyArray = InstanceType<typeof PromiseManyArray>;

Expand Down Expand Up @@ -241,12 +240,7 @@ export default class InternalModel {
} else {
isRecordFullyDeleted = this.currentState.stateName === 'root.deleted.saved';
}
return (
this._isDematerializing ||
this.hasScheduledDestroy() ||
this.isDestroyed ||
isRecordFullyDeleted
);
return this._isDematerializing || this.hasScheduledDestroy() || this.isDestroyed || isRecordFullyDeleted;
}

_isRecordFullyDeleted(): boolean {
Expand Down Expand Up @@ -550,11 +544,7 @@ export default class InternalModel {
this.send('unloadRecord');
this.dematerializeRecord();
if (this._scheduledDestroy === null) {
this._scheduledDestroy = run.backburner.schedule(
'destroy',
this,
'_checkForOrphanedInternalModels'
);
this._scheduledDestroy = run.backburner.schedule('destroy', this, '_checkForOrphanedInternalModels');
}
}

Expand Down Expand Up @@ -616,14 +606,7 @@ export default class InternalModel {
return this.store
._findBelongsToByJsonApiResource(resource, this, relationshipMeta, options)
.then(
internalModel =>
handleCompletedRelationshipRequest(
this,
key,
resource._relationship,
internalModel,
null
),
internalModel => handleCompletedRelationshipRequest(this, key, resource._relationship, internalModel, null),
e => handleCompletedRelationshipRequest(this, key, resource._relationship, null, e)
);
}
Expand All @@ -643,8 +626,7 @@ export default class InternalModel {
};

if (isAsync) {
let internalModel =
resource && resource.data ? store._internalModelForResource(resource.data) : null;
let internalModel = resource && resource.data ? store._internalModelForResource(resource.data) : null;

if (resource!._relationship!.hasFailedLoadAttempt) {
return this._relationshipProxyCache[key];
Expand Down Expand Up @@ -733,8 +715,7 @@ export default class InternalModel {
return manyArray;
})
.then(
manyArray =>
handleCompletedRelationshipRequest(this, key, jsonApi._relationship, manyArray, null),
manyArray => handleCompletedRelationshipRequest(this, key, jsonApi._relationship, manyArray, null),
e => handleCompletedRelationshipRequest(this, key, jsonApi._relationship, null, e)
) as RSVP.Promise<unknown>;
this._relationshipPromisesCache[key] = loadingPromise;
Expand Down Expand Up @@ -1237,10 +1218,7 @@ export default class InternalModel {
let modelClass = relationshipMeta.type;
let data;
if (relationshipMeta.kind === 'hasMany') {
assert(
'You need to pass in an array to set a hasMany property on a record',
Array.isArray(preloadValue)
);
assert('You need to pass in an array to set a hasMany property on a record', Array.isArray(preloadValue));
data = preloadValue.map(value => this._convertPreloadRelationshipToJSON(value, modelClass));
} else {
data = this._convertPreloadRelationshipToJSON(preloadValue, modelClass);
Expand Down Expand Up @@ -1512,9 +1490,7 @@ function assertRecordsPassedToHasMany(records) {
Array.isArray(records) || EmberArray.detect(records)
);
assert(
`All elements of a hasMany relationship must be instances of Model, you passed ${inspect(
records
)}`,
`All elements of a hasMany relationship must be instances of Model, you passed ${inspect(records)}`,
(function() {
return A(records).every(record => record.hasOwnProperty('_internalModel') === true);
})()
Expand Down
9 changes: 7 additions & 2 deletions packages/store/addon/-private/system/references/record.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import Reference from './reference';
*/
export default class RecordReference extends Reference {
public type = this.internalModel.modelName;
private _id = this.internalModel.id;
private get _id() {
return this.internalModel.id;
}

/**
The `id` of the record that this reference refers to.
Expand Down Expand Up @@ -136,7 +138,10 @@ export default class RecordReference extends Reference {
@return {Promise<record>} the record for this RecordReference
*/
load() {
return this.store.findRecord(this.type, this._id);
if (this._id !== null) {
return this.store.findRecord(this.type, this._id);
}
throw new Error(`Unable to fetch record of type ${this.type} without an id`);
}

/**
Expand Down
2 changes: 0 additions & 2 deletions packages/store/addon/-private/system/relationship-meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import { RelationshipSchema } from '../ts-interfaces/record-data-schemas';
import { BRAND_SYMBOL } from '../ts-interfaces/utils/brand';
import Store from './store';

type Store = InstanceType<typeof Store>;

export function typeForRelationshipMeta(meta) {
let modelName;

Expand Down
26 changes: 4 additions & 22 deletions packages/store/addon/-private/system/relationships/state/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,19 @@ import Store from '../../store';
import RecordDataStoreWrapper from '../../store/record-data-store-wrapper';
import { upgradeForInternal } from '../../ts-upgrade-map';

type Store = InstanceType<typeof Store>;

function createRelationshipFor(
relationshipMeta: RelationshipSchema,
store: Store,
recordData: RelationshipRecordData,
key: string
) {
let inverseKey = recordData.storeWrapper.inverseForRelationship(recordData.modelName, key);
let inverseIsAsync = recordData.storeWrapper.inverseIsAsyncForRelationship(
recordData.modelName,
key
);
let inverseIsAsync = recordData.storeWrapper.inverseIsAsyncForRelationship(recordData.modelName, key);

if (relationshipMeta.kind === 'hasMany') {
return new ManyRelationship(store, inverseKey, relationshipMeta, recordData, inverseIsAsync);
} else {
return new BelongsToRelationship(
store,
inverseKey,
relationshipMeta,
recordData,
inverseIsAsync
);
return new BelongsToRelationship(store, inverseKey, relationshipMeta, recordData, inverseIsAsync);
}
}

Expand Down Expand Up @@ -60,17 +49,10 @@ export default class Relationships {

if (!relationship) {
let recordData = this.recordData;
let rel = this.recordData.storeWrapper.relationshipsDefinitionFor(this.recordData.modelName)[
key
];
let rel = this.recordData.storeWrapper.relationshipsDefinitionFor(this.recordData.modelName)[key];

if (rel) {
relationship = relationships[key] = createRelationshipFor(
rel,
this._store,
recordData,
key
);
relationship = relationships[key] = createRelationshipFor(rel, this._store, recordData, key);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import { run as emberRunLoop } from '@ember/runloop';
import { set, get, computed } from '@ember/object';
import { getOwner } from '@ember/application';
import { assign } from '@ember/polyfills';
import { default as RSVP, Promise } from 'rsvp';
import { default as RSVP, all, resolve, Promise, defer } from 'rsvp';
import Service from '@ember/service';
import { typeOf, isPresent, isNone } from '@ember/utils';

import Ember from 'ember';
import { InvalidError } from '@ember-data/adapter/error';
import { assert, deprecate, warn, inspect } from '@ember/debug';
import { assert, warn, deprecate, inspect } from '@ember/debug';
import { DEBUG } from '@glimmer/env';
import Model from './model/model';
import normalizeModelName from './normalize-model-name';
Expand All @@ -38,6 +38,7 @@ import InternalModel from './model/internal-model';
import RecordDataDefault from './model/record-data';
import edBackburner from './backburner';
import { RECORD_DATA_ERRORS, RECORD_DATA_STATE } from '@ember-data/canary-features';
import { Record } from '../ts-interfaces/record';

const badIdFormatAssertion = '`id` passed to `findRecord()` has to be non-empty string or number';
const emberRun = emberRunLoop.backburner;
Expand Down Expand Up @@ -699,7 +700,7 @@ const Store = Service.extend({
@param {Object} preload - optional set of attributes and relationships passed in either as IDs or as actual models
@return {Promise} promise
*/
findRecord(modelName, id, options) {
findRecord(modelName: string, id: string | number, options?: any): Promise<Record> {
if (DEBUG) {
assertDestroyingStore(this, 'findRecord');
}
Expand Down Expand Up @@ -751,7 +752,7 @@ const Store = Service.extend({
return Promise.resolve(internalModel);
},

_findByInternalModel(internalModel, options = {}) {
_findByInternalModel(internalModel, options: { preload?: any } = {}) {
if (options.preload) {
internalModel.preloadData(options.preload);
}
Expand Down Expand Up @@ -805,7 +806,7 @@ const Store = Service.extend({
promises[i] = this.findRecord(normalizedModelName, ids[i]);
}

return promiseArray(RSVP.all(promises).then(A, null, `DS: Store#findByIds of ${normalizedModelName} complete`));
return promiseArray(all(promises).then(A, null, `DS: Store#findByIds of ${normalizedModelName} complete`));
},

/**
Expand Down Expand Up @@ -847,8 +848,13 @@ const Store = Service.extend({
}

let { id, modelName } = internalModel;
let resolver = RSVP.defer(`Fetching ${modelName}' with id: ${id}`);
let pendingFetchItem = {
let resolver = defer(`Fetching ${modelName}' with id: ${id}`);
let pendingFetchItem: {
internalModel: InternalModel;
resolver: RSVP.Deferred<unknown>;
options: any;
trace?: Error;
} = {
internalModel,
resolver,
options,
Expand Down Expand Up @@ -937,7 +943,7 @@ const Store = Service.extend({
}

// reject missing records
let missingInternalModels = [];
let missingInternalModels: InternalModel[] = [];

for (let i = 0, l = expectedInternalModels.length; i < l; i++) {
let internalModel = expectedInternalModels[i];
Expand All @@ -961,10 +967,10 @@ const Store = Service.extend({
}
}

function rejectInternalModels(internalModels, error) {
function rejectInternalModels(internalModels: InternalModel[], error?: Error) {
for (let i = 0, l = internalModels.length; i < l; i++) {
let internalModel = internalModels[i];
let pair = seeking[internalModel.id];
let pair = seeking[internalModel.id!];

if (pair) {
pair.resolver.reject(
Expand Down Expand Up @@ -1302,7 +1308,7 @@ const Store = Service.extend({

_findHasManyByJsonApiResource(resource, parentInternalModel, relationshipMeta, options) {
if (!resource) {
return RSVP.resolve([]);
return resolve([]);
}

let {
Expand All @@ -1326,7 +1332,9 @@ const Store = Service.extend({
if (shouldFindViaLink) {
return this.findHasMany(parentInternalModel, resource.links.related, relationshipMeta, options).then(
internalModels => {
let payload = { data: internalModels.map(im => recordDataFor(im).getResourceIdentifier()) };
let payload: { data: any[]; meta?: any } = {
data: internalModels.map(im => recordDataFor(im).getResourceIdentifier()),
};
if (internalModels.meta !== undefined) {
payload.meta = internalModels.meta;
}
Expand Down Expand Up @@ -1359,7 +1367,7 @@ const Store = Service.extend({

// we were explicitly told we have no data and no links.
// TODO if the relationshipIsStale, should we hit the adapter anyway?
return RSVP.resolve([]);
return resolve([]);
},

_getHasManyByJsonApiResource(resource) {
Expand Down Expand Up @@ -1399,7 +1407,7 @@ const Store = Service.extend({
_fetchBelongsToLinkFromResource(resource, parentInternalModel, relationshipMeta, options) {
if (!resource || !resource.links || !resource.links.related) {
// should we warn here, not sure cause its an internal method
return RSVP.resolve(null);
return resolve(null);
}
return this.findBelongsTo(parentInternalModel, resource.links.related, relationshipMeta, options).then(
internalModel => {
Expand All @@ -1416,7 +1424,7 @@ const Store = Service.extend({

_findBelongsToByJsonApiResource(resource, parentInternalModel, relationshipMeta, options) {
if (!resource) {
return RSVP.resolve(null);
return resolve(null);
}

let internalModel = resource.data ? this._internalModelForResource(resource.data) : null;
Expand Down Expand Up @@ -1460,7 +1468,7 @@ const Store = Service.extend({
We have canonical data, but our local state is empty
*/
if (localDataIsEmpty) {
return RSVP.resolve(null);
return resolve(null);
}

return this._findByInternalModel(internalModel, options);
Expand All @@ -1469,7 +1477,7 @@ const Store = Service.extend({
let resourceIsLocal = !localDataIsEmpty && resource.data.id === null;

if (resourceIsLocal) {
return RSVP.resolve(internalModel.getRecord());
return resolve(internalModel.getRecord());
}

// fetch by data
Expand All @@ -1481,7 +1489,7 @@ const Store = Service.extend({

// we were explicitly told we have no data and no links.
// TODO if the relationshipIsStale, should we hit the adapter anyway?
return RSVP.resolve(null);
return resolve(null);
},

/**
Expand Down Expand Up @@ -1545,7 +1553,7 @@ const Store = Service.extend({
typeof modelName === 'string'
);

let adapterOptionsWrapper = {};
let adapterOptionsWrapper: { adapterOptions?: any } = {};

if (options && options.adapterOptions) {
adapterOptionsWrapper.adapterOptions = options.adapterOptions;
Expand Down Expand Up @@ -1684,7 +1692,7 @@ const Store = Service.extend({

let normalizedModelName = normalizeModelName(modelName);
let adapter = this.adapterFor(normalizedModelName);
let adapterOptionsWrapper = {};
let adapterOptionsWrapper: { adapterOptions?: any } = {};

if (options && options.adapterOptions) {
adapterOptionsWrapper.adapterOptions = options.adapterOptions;
Expand Down Expand Up @@ -1920,7 +1928,7 @@ const Store = Service.extend({
@param {RecordArray} array
@return {Promise} promise
*/
_fetchAll(modelName, array, options = {}) {
_fetchAll(modelName, array, options: { reload?: boolean; backgroundReload?: boolean } = {}) {
let adapter = this.adapterFor(modelName);

assert(`You tried to load all records but you have no adapter (for ${modelName})`, adapter);
Expand Down Expand Up @@ -3319,4 +3327,6 @@ if (DEBUG) {
};
}

type Store = InstanceType<typeof Store>;

export default Store;
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { BRAND_SYMBOL } from '../../ts-interfaces/utils/brand';
import { upgradeForInternal } from '../ts-upgrade-map';
import RecordData from '../../ts-interfaces/record-data';

type Store = InstanceType<typeof Store>;
type StringOrNullOrUndefined = string | null | undefined;

const MISSING_ID_ARG_ERROR_MESSAGE = `Either an id or a clientId is required as an argument.`;
Expand Down
2 changes: 2 additions & 0 deletions packages/store/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
},
"devDependencies": {
"@ember/optional-features": "*",
"@types/ember": "*",
"@types/rsvp": "*",
"broccoli-asset-rev": "*",
"ember-cli": "*",
"ember-cli-dependency-checker": "*",
Expand Down
Loading