Skip to content

Commit

Permalink
Merge pull request #6985 from emberjs/fix/record-data-fix
Browse files Browse the repository at this point in the history
[FIX] RecordData is not a constructor
  • Loading branch information
hjdivad authored Jan 22, 2020
2 parents ee3a74c + f95c2ba commit 88d35d9
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 58 deletions.
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

# compiled output
**/dist/
**/dist-control/
**/dist-experiment/
**/tmp/
/packages/-ember-data/docs/

Expand Down
3 changes: 1 addition & 2 deletions packages/-ember-data/addon/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import JSONSerializer from '@ember-data/serializer/json';
import JSONAPISerializer from '@ember-data/serializer/json-api';
import RESTSerializer, { EmbeddedRecordsMixin } from '@ember-data/serializer/rest';
import Transform from '@ember-data/serializer/transform';
import { normalizeModelName } from '@ember-data/store';
import Store, { normalizeModelName } from '@ember-data/store';

import {
AdapterPopulatedRecordArray,
Expand All @@ -45,7 +45,6 @@ import {
} from './-private';
import initializeStoreService from './initialize-store-service';
import setupContainer from './setup-container';
import Store from './store';

if (VERSION.match(/^1\.([0-9]|1[0-2])\./)) {
throw new EmberError(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import {
CollectionResourceRelationship,
SingleResourceRelationship,
} from '@ember-data/store/-private/ts-interfaces/ember-data-json-api';
import { RecordData } from '@ember-data/store/-private/ts-interfaces/record-data';

type SingleResourceRelationship = import('@ember-data/store/-private/ts-interfaces/ember-data-json-api').SingleResourceRelationship;
type CollectionResourceRelationship = import('@ember-data/store/-private/ts-interfaces/ember-data-json-api').CollectionResourceRelationship;
type RecordData = import('@ember-data/store/-private/ts-interfaces/record-data').RecordData;
type ConfidentDict<T> = import('@ember-data/store/-private/ts-interfaces/utils').ConfidentDict<T>;
type HasManyRelationship = import('../relationships/state/has-many').default;
type BelongsToRelationship = import('../relationships/state/belongs-to').default;
Expand Down
74 changes: 53 additions & 21 deletions packages/store/addon/-private/system/core-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
HAS_ADAPTER_PACKAGE,
HAS_EMBER_DATA_PACKAGE,
HAS_MODEL_PACKAGE,
HAS_RECORD_DATA_PACKAGE,
HAS_SERIALIZER_PACKAGE,
} from '@ember-data/private-build-infra';
import {
Expand Down Expand Up @@ -94,7 +95,9 @@ type AttributesSchema = import('../ts-interfaces/record-data-schemas').Attribute
type SchemaDefinitionService = import('../ts-interfaces/schema-definition-service').SchemaDefinitionService;
type PrivateSnapshot = import('./snapshot').PrivateSnapshot;
type Relationship = import('@ember-data/record-data/-private').Relationship;
type RecordDataClass = typeof import('@ember-data/record-data/-private').RecordData;

let _RecordData: RecordDataClass | undefined;
const emberRun = emberRunLoop.backburner;

const { ENV } = Ember;
Expand Down Expand Up @@ -412,14 +415,16 @@ abstract class CoreStore extends Service {
if (REQUEST_SERVICE) {
return this._fetchManager.requestCache;
}
throw new Error('RequestService is not available unless the feature flag is on and running on a canary build');

assertInDebug('RequestService is not available unless the feature flag is on and running on a canary build', false);
}

get identifierCache(): IdentifierCache {
if (!IDENTIFIERS) {
throw new Error(`Store.identifierCache is unavailable in this build of EmberData`);
if (IDENTIFIERS) {
return identifierCacheFor(this);
}
return identifierCacheFor(this);

assertInDebug(`Store.identifierCache is unavailable in this build of EmberData`, false);
}

_instantiateRecord(
Expand Down Expand Up @@ -475,9 +480,9 @@ abstract class CoreStore extends Service {
setRecordIdentifier(record, identifier);
//recordToInternalModelMap.set(record, internalModel);
return record;
} else {
throw new Error('should not be here, custom model class ff error');
}

assertInDebug('should not be here, custom model class ff error', false);
}

abstract instantiateRecord(
Expand Down Expand Up @@ -517,9 +522,9 @@ abstract class CoreStore extends Service {
getSchemaDefinitionService(): SchemaDefinitionService {
if (CUSTOM_MODEL_CLASS) {
return this._schemaDefinitionService;
} else {
throw new Error('need to enable CUSTOM_MODEL_CLASS feature flag in order to access SchemaDefinitionService');
}

assertInDebug('need to enable CUSTOM_MODEL_CLASS feature flag in order to access SchemaDefinitionService', false);
}

// TODO Double check this return value is correct
Expand Down Expand Up @@ -3060,9 +3065,9 @@ abstract class CoreStore extends Service {
let internalModel = internalModelFactoryFor(this).peek(identifier);
// TODO we used to check if the record was destroyed here
return internalModel!.createSnapshot(options).serialize(options);
} else {
throw new Error('serializeRecord is only available when CUSTOM_MODEL_CLASS ff is on');
}

assertInDebug('serializeRecord is only available when CUSTOM_MODEL_CLASS ff is on', false);
}

saveRecord(record: RecordInstance, options?: Dict<unknown>): RSVP.Promise<RecordInstance> {
Expand All @@ -3073,9 +3078,9 @@ abstract class CoreStore extends Service {
// Casting can be removed once REQUEST_SERVICE ff is turned on
// because a `Record` is provided there will always be a matching internalModel
return (internalModel!.save(options) as RSVP.Promise<void>).then(() => record);
} else {
throw new Error('saveRecord is only available when CUSTOM_MODEL_CLASS ff is on');
}

assertInDebug('saveRecord is only available when CUSTOM_MODEL_CLASS ff is on', false);
}

relationshipReferenceFor(identifier: RecordIdentifier, key: string): BelongsToReference | HasManyReference {
Expand All @@ -3084,9 +3089,9 @@ abstract class CoreStore extends Service {
let internalModel = internalModelFactoryFor(this).peek(stableIdentifier);
// TODO we used to check if the record was destroyed here
return internalModel!.referenceFor(null, key);
} else {
throw new Error('relationshipReferenceFor is only available when CUSTOM_MODEL_CLASS ff is on');
}

assertInDebug('relationshipReferenceFor is only available when CUSTOM_MODEL_CLASS ff is on', false);
}

/**
Expand All @@ -3111,7 +3116,29 @@ abstract class CoreStore extends Service {
clientId: string,
storeWrapper: RecordDataStoreWrapper
): RecordData {
throw new Error(`Expected store.createRecordDataFor to be implemented but it wasn't`);
if (HAS_RECORD_DATA_PACKAGE) {
// we can't greedily use require as this causes
// a cycle we can't easily fix (or clearly pin point) at present.
//
// it can be reproduced in partner tests by running
// node ./bin/packages-for-commit.js && yarn test-external:ember-observer
if (_RecordData === undefined) {
_RecordData = require('@ember-data/record-data/-private').RecordData as RecordDataClass;
}

if (IDENTIFIERS) {
let identifier = identifierCacheFor(this).getOrCreateRecordIdentifier({
type: modelName,
id,
lid: clientId,
});
return new _RecordData(identifier, storeWrapper);
} else {
return new _RecordData(modelName, id, clientId, storeWrapper);
}
}

assertInDebug(`Expected store.createRecordDataFor to be implemented but it wasn't`, false);
}

/**
Expand Down Expand Up @@ -3179,10 +3206,11 @@ abstract class CoreStore extends Service {
}

newClientId() {
if (IDENTIFIERS) {
throw new Error(`Private API Removed`);
if (!IDENTIFIERS) {
return globalClientIdCounter++;
}
return globalClientIdCounter++;

assertInDebug(`Private API Removed`, false);
}

// ...............
Expand Down Expand Up @@ -3732,10 +3760,14 @@ function internalModelForRelatedResource(
return store._internalModelForResource(identifier);
}

function assertInDebug(msg: string, cond: boolean = false): asserts cond is true {
if (DEBUG && cond) {
throw new Error(msg);
}
}

function assertIdentifierHasId(
identifier: StableRecordIdentifier
): asserts identifier is StableExistingRecordIdentifier {
if (DEBUG && identifier.id === null) {
throw new Error(`Attempted to schedule a fetch for a record without an id.`);
}
assertInDebug(`Attempted to schedule a fetch for a record without an id.`, identifier.id === null);
}
33 changes: 5 additions & 28 deletions packages/store/addon/-private/system/ds-model-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,14 @@ import { assign } from '@ember/polyfills';
import { isPresent } from '@ember/utils';
import { DEBUG } from '@glimmer/env';

import { CUSTOM_MODEL_CLASS, IDENTIFIERS } from '@ember-data/canary-features';
import { HAS_RECORD_DATA_PACKAGE } from '@ember-data/private-build-infra';
import { CUSTOM_MODEL_CLASS } from '@ember-data/canary-features';

import { identifierCacheFor } from '../identifiers/cache';
import CoreStore from './core-store';
import notifyChanges from './model/notify-changes';
import { getShimClass } from './model/shim-model-class';
import normalizeModelName from './normalize-model-name';
import { DSModelSchemaDefinitionService, getModelFactory } from './schema-definition-service';

type RecordDataStoreWrapper = import('./store/record-data-store-wrapper').default;

const RecordData = HAS_RECORD_DATA_PACKAGE ? require('@ember-data/record-data/-private').RecordData : null;

type RelationshipsSchema = import('../ts-interfaces/record-data-schemas').RelationshipsSchema;
type SchemaDefinitionService = import('../ts-interfaces/schema-definition-service').SchemaDefinitionService;
type RecordDataRecordWrapper = import('../ts-interfaces/record-data-record-wrapper').RecordDataRecordWrapper;
Expand Down Expand Up @@ -142,31 +136,14 @@ class Store extends CoreStore {
record.destroy();
}

createRecordDataFor(modelName: string, id: string | null, clientId: string, storeWrapper: RecordDataStoreWrapper) {
if (HAS_RECORD_DATA_PACKAGE) {
if (IDENTIFIERS) {
let identifier = identifierCacheFor(this).getOrCreateRecordIdentifier({
type: modelName,
id,
lid: clientId,
});
return new RecordData(identifier, storeWrapper);
} else {
return new RecordData(modelName, id, clientId, storeWrapper);
}
} else {
throw new Error(`Expected store.createRecordDataFor to be implemented but it wasn't`);
}
}

/**
Returns the model class for the particular `modelName`.
The class of a model might be useful if you want to get a list of all the
relationship names of the model, see
[`relationshipNames`](/ember-data/release/classes/Model?anchor=relationshipNames)
for example.
@method modelFor
@param {String} modelName
@return {Model}
Expand Down Expand Up @@ -215,10 +192,10 @@ class Store extends CoreStore {
This exists for legacy support for the RESTSerializer,
which due to how it must guess whether a key is a model
must query for whether a match exists.
We should investigate an RFC to make this public or removing
this requirement.
@private
*/
_hasModelFor(modelName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ export default Route.extend({
});
},
afterModel() {
if (document.location.href.indexOf('?tracing') !== -1 || document.location.href.indexOf('?tracerbench=true') !== -1) {
if (
document.location.href.indexOf('?tracing') !== -1 ||
document.location.href.indexOf('?tracerbench=true') !== -1
) {
endTrace();
}
},
Expand Down

0 comments on commit 88d35d9

Please sign in to comment.