Skip to content

Commit

Permalink
stash refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
runspired committed Mar 26, 2023
1 parent 1410dc2 commit 3003386
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 117 deletions.
16 changes: 16 additions & 0 deletions packages/-ember-data/addon/-private/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,31 @@ import PromiseProxyMixin from '@ember/object/promise-proxy-mixin';
import ObjectProxy from '@ember/object/proxy';

import { LegacyNetworkHandler } from '@ember-data/legacy-compat';
import { _modelFor, instantiateRecord, SchemaService, teardownRecord } from '@ember-data/model/hooks';
import { RequestManager } from '@ember-data/request';
import { Fetch } from '@ember-data/request/fetch';
import BaseStore from '@ember-data/store';
import type { StableRecordIdentifier } from '@ember-data/types/q/identifier';
import { RecordInstance } from '@ember-data/types/q/record-instance';

export class Store extends BaseStore {
constructor(args: Record<string, unknown>) {
super(args);
this.requestManager = new RequestManager();
this.requestManager.use([LegacyNetworkHandler, Fetch]);
this.registerSchemaDefinitionService(new SchemaService(this));
}

instantiateRecord(identifier: StableRecordIdentifier, args: Record<string, unknown>) {
return instantiateRecord(this, identifier, args);
}

teardownRecord(record: RecordInstance) {
teardownRecord(this, record);
}

modelFor(type: string) {
return _modelFor(this, type) || super.modelFor(type);
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/model/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default {
plugins: [
// These are the modules that users should be able to import from your
// addon. Anything not listed here may get optimized away.
addon.publicEntrypoints(['index.js', 'error.js', 'json-api.js', 'rest.js', '-private.js']),
addon.publicEntrypoints(['index.js', '-private.js', 'hooks.js']),

nodeResolve({ extensions: ['.ts', '.js'] }),
babel({
Expand Down
1 change: 0 additions & 1 deletion packages/model/src/-private.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export { default as Errors } from './-private/errors';
export { default as ManyArray } from './-private/many-array';
export { default as PromiseBelongsTo } from './-private/promise-belongs-to';
export { default as PromiseManyArray } from './-private/promise-many-array';
export { default as _modelForMixin } from './-private/model-for-mixin';

// // Used by tests
export { default as diffArray } from './-private/diff-array';
Expand Down
77 changes: 77 additions & 0 deletions packages/model/src/-private/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { getOwner, setOwner } from '@ember/application';
import { assert } from '@ember/debug';

import { DEPRECATE_V1_RECORD_DATA } from '@ember-data/private-build-infra/deprecations';
import type Store from '@ember-data/store';
import { setCacheFor, setRecordIdentifier, StoreMap } from '@ember-data/store/-private';
import type { CreateRecordProperties } from '@ember-data/store/-private/store-service';
import type { Cache } from '@ember-data/types/cache/cache';
import type { DSModel } from '@ember-data/types/q/ds-model';
import type { StableRecordIdentifier } from '@ember-data/types/q/identifier';
import type { RecordInstance } from '@ember-data/types/q/record-instance';

import { getModelFactory } from './schema-definition-service';

export function instantiateRecord(
store: Store,
identifier: StableRecordIdentifier,
createRecordArgs: { [key: string]: unknown }
): RecordInstance {
let modelName = identifier.type;

const cache = DEPRECATE_V1_RECORD_DATA ? store._instanceCache.getResourceCache(identifier) : store.cache;
// TODO deprecate allowing unknown args setting
let createOptions: CreateRecordProperties = {
_createProps: createRecordArgs,
// TODO @deprecate consider deprecating accessing record properties during init which the below is necessary for
_secretInit: {
identifier,
cache,
store,
cb: secretInit,
},
};

// ensure that `getOwner(this)` works inside a model instance
setOwner(createOptions, getOwner(store)!);
return getModelFactory(this, this._modelFactoryCache, modelName).class.create(createOptions);
}

function secretInit(record: RecordInstance, cache: Cache, identifier: StableRecordIdentifier, store: Store): void {
setRecordIdentifier(record, identifier);
StoreMap.set(record, store);
setCacheFor(record, cache);
}

export function teardownRecord(store: Store, record: RecordInstance) {
assert(
`expected to receive an instance of DSModel. If using a custom model make sure you implement teardownRecord`,
'destroy' in record
);
(record as DSModel).destroy();
}

export function _modelFor(store: Store, modelName: string) {
assert(`Attempted to call store.modelFor(), but the store instance has already been destroyed.`, !store.isDestroyed);
assert(`You need to pass a model name to the store's modelFor method`, modelName);
assert(
`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${modelName}`,
typeof modelName === 'string'
);
let normalizedModelName = normalizeModelName(modelName);
let maybeFactory = getModelFactory(store, store._modelFactoryCache, normalizedModelName);

// for factorFor factory/class split
let klass = maybeFactory && maybeFactory.class ? maybeFactory.class : maybeFactory;
if (!klass || !klass.isModel || store._forceShim) {
assert(
`No model was found for '${modelName}' and no schema handles the type`,
store.getSchemaDefinitionService().doesTypeExist(modelName)
);

return null;
} else {
// TODO @deprecate ever returning the klass, always return the shim
return klass;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { getOwner } from '@ember/application';

import type Store from '@ember-data/store';

import Model from './model';
import Model from '../model';

/*
In case someone defined a relationship to a mixin, for example:
Expand All @@ -25,7 +25,7 @@ import Model from './model';
*/
export default function modelForMixin(store: Store, normalizedModelName: string): Model | null {
let owner: any = getOwner(store);
let MaybeMixin = owner.factoryFor(`mixin:${normalizedModelName}`);
let MaybeMixin: any = owner.factoryFor(`mixin:${normalizedModelName}`);
let mixin = MaybeMixin && MaybeMixin.class;
if (mixin) {
let ModelForMixin = Model.extend(mixin);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,30 @@
import { getOwner } from '@ember/application';
import { deprecate } from '@ember/debug';

import { importSync } from '@embroider/macros';

import type Model from '@ember-data/model';
import { HAS_MODEL_PACKAGE } from '@ember-data/private-build-infra';
import { DEPRECATE_STRING_ARG_SCHEMAS } from '@ember-data/private-build-infra/deprecations';
import type Store from '@ember-data/store';
import { ___normalizeModelName } from '@ember-data/store/-private';
import { DSModelSchema } from '@ember-data/types/q/ds-model';
import type { RecordIdentifier } from '@ember-data/types/q/identifier';
import type { AttributesSchema, RelationshipsSchema } from '@ember-data/types/q/record-data-schemas';

import type Store from '../store-service';
import normalizeModelName from '../utils/normalize-model-name';

type ModelForMixin = (store: Store, normalizedModelName: string) => Model | null;

let _modelForMixin: ModelForMixin;
if (HAS_MODEL_PACKAGE) {
let _found;
_modelForMixin = function () {
if (!_found) {
_found = (importSync('@ember-data/model/-private') as typeof import('@ember-data/model/-private'))._modelForMixin;
}
return _found(...arguments);
};
}
import _modelForMixin from './model-for-mixin';

export class DSModelSchemaDefinitionService {
declare store: Store;
declare _relationshipsDefCache;
declare _attributesDefCache;
declare _relationshipsDefCache: Record<string, RelationshipsSchema>;
declare _attributesDefCache: Record<string, AttributesSchema>;

constructor(store: Store) {
this.store = store;
this._relationshipsDefCache = Object.create(null);
this._attributesDefCache = Object.create(null);
this._relationshipsDefCache = Object.create(null) as Record<string, RelationshipsSchema>;
this._attributesDefCache = Object.create(null) as Record<string, AttributesSchema>;
}

// Following the existing RD implementation
attributesDefinitionFor(identifier: RecordIdentifier | { type: string }): AttributesSchema {
let modelName, attributes;
let modelName: string, attributes: AttributesSchema;
if (DEPRECATE_STRING_ARG_SCHEMAS) {
if (typeof identifier === 'string') {
deprecate(
Expand All @@ -62,10 +48,10 @@ export class DSModelSchemaDefinitionService {
attributes = this._attributesDefCache[modelName];

if (attributes === undefined) {
let modelClass = this.store.modelFor(modelName);
let modelClass = this.store.modelFor(modelName) as DSModelSchema;
let attributeMap = modelClass.attributes;

attributes = Object.create(null);
attributes = Object.create(null) as AttributesSchema;
attributeMap.forEach((meta, name) => (attributes[name] = meta));
this._attributesDefCache[modelName] = attributes;
}
Expand All @@ -75,7 +61,7 @@ export class DSModelSchemaDefinitionService {

// Following the existing RD implementation
relationshipsDefinitionFor(identifier: RecordIdentifier | { type: string }): RelationshipsSchema {
let modelName, relationships;
let modelName: string, relationships: RelationshipsSchema;
if (DEPRECATE_STRING_ARG_SCHEMAS) {
if (typeof identifier === 'string') {
deprecate(
Expand All @@ -99,34 +85,40 @@ export class DSModelSchemaDefinitionService {
relationships = this._relationshipsDefCache[modelName];

if (relationships === undefined) {
let modelClass = this.store.modelFor(modelName);
relationships = modelClass.relationshipsObject || null;
let modelClass = this.store.modelFor(modelName) as DSModelSchema;
relationships = modelClass.relationshipsObject || {};
this._relationshipsDefCache[modelName] = relationships;
}

return relationships;
}

doesTypeExist(modelName: string): boolean {
let normalizedModelName = normalizeModelName(modelName);
let normalizedModelName = ___normalizeModelName(modelName);
let factory = getModelFactory(this.store, this.store._modelFactoryCache, normalizedModelName);

return factory !== null;
}
}

export function getModelFactory(store: Store, cache, normalizedModelName: string): Model | null {
type ModelFactory = {
class: DSModelSchema;
};

export function getModelFactory(
store: Store,
cache: Record<string, ModelFactory>,
normalizedModelName: string
): Model | null {
let factory = cache[normalizedModelName];

if (!factory) {
let owner: any = getOwner(store);
factory = owner.factoryFor(`model:${normalizedModelName}`);
let owner = getOwner(store);
factory = owner.factoryFor(`model:${normalizedModelName}`) as unknown as ModelFactory;

if (HAS_MODEL_PACKAGE) {
if (!factory) {
//Support looking up mixins as base types for polymorphic relationships
factory = _modelForMixin(store, normalizedModelName);
}
if (!factory) {
//Support looking up mixins as base types for polymorphic relationships
factory = _modelForMixin(store, normalizedModelName);
}

if (!factory) {
Expand All @@ -137,7 +129,7 @@ export function getModelFactory(store: Store, cache, normalizedModelName: string
let klass = factory.class;

if (klass.isModel) {
let hasOwnModelNameSet = klass.modelName && Object.prototype.hasOwnProperty.call(klass, 'modelName');
let hasOwnModelNameSet = !!klass.modelName && Object.prototype.hasOwnProperty.call(klass, 'modelName');
if (!hasOwnModelNameSet) {
Object.defineProperty(klass, 'modelName', { value: normalizedModelName });
}
Expand Down
2 changes: 2 additions & 0 deletions packages/model/src/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { instantiateRecord, teardownRecord, _modelFor } from './-private/hooks';
export { DSModelSchemaDefinitionService as SchemaService } from './-private/hooks/schema-definition-service';
5 changes: 5 additions & 0 deletions packages/store/src/-private/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ export function normalizeModelName(modelName: string) {
}
assert(`normalizeModelName support has been removed`);
}
export { _normalize as ___normalizeModelName };

// @ember-data/model needs these temporarily
export { setRecordIdentifier, StoreMap } from './caches/instance-cache';
export { setCacheFor } from './caches/cache-utils';

// TODO this should be a deprecated helper but we have so much usage of it
// to also eliminate
Expand Down
Loading

0 comments on commit 3003386

Please sign in to comment.