Skip to content

Commit

Permalink
implement store portion of v2 cache (#8114)
Browse files Browse the repository at this point in the history
* implement store portion of v2 cache

* cleanup and add docs

* all the docs

* fix type import

* cleanup

* be stricter

* more strict

* explore stricter

* cleanup
  • Loading branch information
runspired authored Aug 11, 2022
1 parent df1381b commit 8e6b742
Show file tree
Hide file tree
Showing 40 changed files with 1,147 additions and 412 deletions.
3 changes: 2 additions & 1 deletion ember-data-types/q/record-data-schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ export interface AttributeSchema {
/**
* @internal
*/
kind: 'attribute'; // TODO @runspired remove usage or guard internally
name: string;

kind?: 'attribute';

// TODO @runspired update RFC to make options optional
options: {
[key: string]: unknown;
Expand Down
211 changes: 205 additions & 6 deletions ember-data-types/q/record-data-store-wrapper.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,255 @@
import { IdentifierCache } from '@ember-data/store/-private/caches/identifier-cache';
import { NotificationType } from '@ember-data/store/-private/managers/record-notification-manager';

import { StableRecordIdentifier } from './identifier';
import type { RecordData } from './record-data';
import type { AttributesSchema, RelationshipsSchema } from './record-data-schemas';
import { SchemaDefinitionService } from './schema-definition-service';

/**
@module @ember-data/store
*/

/**
* Provides encapsulated API access to a minimal subset of store service's
* functionality for RecordData implementations.
* RecordDataStoreWrapper provides encapsulated API access to the minimal
* subset of the Store's functionality that cache (RecordData) implementations
* should interact with. It is provided to the Store's `createRecordDataFor`
* hook.
*
* Cache implementations should not need more than this API provides.
*
* This class cannot be directly instantiated.
*
* @class RecordDataStoreWrapper
* @public
*/
export interface RecordDataStoreWrapper {
export interface LegacyRecordDataStoreWrapper {
/**
* Provides access to the IdentifierCache instance
* for this Store instance.
*
* The IdentifierCache can be used to peek, generate or
* retrieve a stable unique identifier for any resource.
*
* @property {IdentifierCache} identifierCache
* @public
*/
identifierCache: IdentifierCache;

/**
* Provides access to the SchemaDefinitionService instance
* for this Store instance.
*
* The SchemaDefinitionService can be used to query for
* information about the schema of a resource.
*
* @method getSchemaDefinitionService
* @public
*/
getSchemaDefinitionService(): SchemaDefinitionService;

/**
* Proxies to the schema service's `relationshipsDefinitionFor`
* method.
*
* Use `wrapper.getSchemaDefinitionService().relationshipsDefinitionFor()`
* instead.
*
* @method relationshipsDefinitionFor
* @param {string} modelName
* @returns {RelationshipsSchema}
* @public
* @deprecated
*/
relationshipsDefinitionFor(modelName: string): RelationshipsSchema;

/**
* Proxies to the schema service's `attributesDefinitionFor`
* method.
*
* Use `wrapper.getSchemaDefinitionService().attributesDefinitionFor()`
* instead.
*
* @method attributesDefinitionFor
* @param {string} modelName
* @returns {AttributesSchema}
* @public
* @deprecated
*/
attributesDefinitionFor(modelName: string): AttributesSchema;

/**
* update the `id` for the record of type `modelName` with the corresponding `clientId`
* Update the `id` for the record corresponding to the identifier
* This operation can only be done for records whose `id` is `null`.
*
* @method setRecordId
* @param {StableRecordIdentifier} identifier;
* @param {string} id;
* @public
*/
setRecordId(modelName: string, id: string, clientId: string): void;
setRecordId(identifier: StableRecordIdentifier, id: string): void;

/**
* Signal to the store that the specified record may be considered fully
* removed from the cache. Generally this means that not only does no
* data exist for the identified resource, no known relationships still
* point to it either.
*
* @method disconnectRecord
* @param {StableRecordIdentifier} identifier
* @public
*/
disconnectRecord(modelName: string, id: string | null, clientId: string): void;
disconnectRecord(modelName: string, id: string, clientId?: string | null): void;
disconnectRecord(modelName: string, id: string | null, clientId?: string | null): void;
disconnectRecord(identifier: StableRecordIdentifier): void;

/**
* Use hasRecord instead.
*
* @method isRecordInUse
* @param modelName
* @param id
* @param clientId
* @public
* @deprecated
*/
isRecordInUse(modelName: string, id: string | null, clientId: string): boolean;
isRecordInUse(modelName: string, id: string, clientId?: string | null): boolean;
isRecordInUse(modelName: string, id: string | null, clientId?: string | null): boolean;

/**
* Use this method to determine if the Store has an instantiated record associated
* with an identifier.
*
* @method hasRecord
* @param identifier
* @returns {boolean}
* @public
*/
hasRecord(identifier: StableRecordIdentifier): boolean;

/**
* Use notifyChange
*
* @method notifyPropertyChange
* @param modelName
* @param id
* @param clientId
* @param key
* @deprecated
* @public
*/
notifyPropertyChange(modelName: string, id: string | null, clientId: string | null, key: string): void;

/**
* Use notifyChange
*
* @method notifyHasManyChange
* @param modelName
* @param id
* @param clientId
* @param key
* @public
* @deprecated
*/
notifyHasManyChange(modelName: string, id: string | null, clientId: string, key: string): void;
notifyHasManyChange(modelName: string, id: string, clientId: string | null | undefined, key: string): void;
notifyHasManyChange(modelName: string, id: string | null, clientId: string | null | undefined, key: string): void;

/**
* Used to retrieve the associated RecordData for a given identifier.
*
* To generate a RecordData for a new client-side resource that does not
* yet have an ID and place it in the new state, first create an identifier
* via `identifierCache.createIdentifierForNewRecord`
*
* Then once you have obtained the RecordData instance you should invoke
* `recordData.clientDidCreate` to ensure the cache entry is put into the
* correct "newly created" state.
*
* @method recordDataFor
* @param {StableRecordIdentifier} identifier
* @return {RecordData} the RecordData cache instance associated with the identifier
* @public
*/
recordDataFor(type: string, id: string, lid?: string | null): RecordData;
recordDataFor(type: string, id: string | null, lid: string): RecordData;
recordDataFor(type: string): RecordData;
recordDataFor(type: string, id?: string | null, lid?: string | null): RecordData;
recordDataFor(identifier: StableRecordIdentifier): RecordData;

/**
* Use notifyChange
*
* @method notifyBelongsToChange
* @param modelName
* @param id
* @param clientId
* @param key
* @public
* @deprecated
*/
notifyBelongsToChange(modelName: string, id: string | null, clientId: string, key: string): void;
notifyBelongsToChange(modelName: string, id: string, clientId: string | null | undefined, key: string): void;
notifyBelongsToChange(modelName: string, id: string | null, clientId: string | null | undefined, key: string): void;

inverseForRelationship(modelName: string, key: string): string | null;
/**
* Notify subscribers of the RecordNotificationManager that cache state has changed.
*
* `attributes` and `relationships` do not require a key, but if one is specified it
* is assumed to be the name of the attribute or relationship that has been updated.
*
* No other namespaces currently expect the `key` argument.
*
* @method notifyChange
* @param {StableRecordIdentifier} identifier
* @param {'attributes' | 'relationships' | 'identity' | 'errors' | 'meta' | 'state'} namespace
* @param {string|undefined} key
* @public
*/
notifyChange(identifier: StableRecordIdentifier, namespace: NotificationType, key?: string): void;

inverseIsAsyncForRelationship(modelName: string, key: string): boolean;
/**
* Use notifyChange
*
* @method notifyErrorsChange
* @param modelName
* @param id
* @param clientId
* @public
* @deprecated
*/
notifyErrorsChange(modelName: string, id: string | null, clientId: string | null): void;

/**
* Use notifyChange
*
* @method notifyStateChange
* @param modelName
* @param id
* @param clientId
* @param key
* @public
* @deprecated
*/
notifyStateChange(modelName: string, id: string | null, clientId: string | null, key?: string): void;
}

export interface V2RecordDataStoreWrapper {
identifierCache: IdentifierCache;
getSchemaDefinitionService(): SchemaDefinitionService;

setRecordId(identifier: StableRecordIdentifier, id: string): void;

disconnectRecord(identifier: StableRecordIdentifier): void;

hasRecord(identifier: StableRecordIdentifier): boolean;

recordDataFor(identifier: StableRecordIdentifier): RecordData;

notifyChange(identifier: StableRecordIdentifier, namespace: NotificationType, key?: string): void;
}

export type RecordDataStoreWrapper = LegacyRecordDataStoreWrapper | V2RecordDataStoreWrapper;
2 changes: 0 additions & 2 deletions ember-data-types/q/record-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ export interface RecordData {

// ----- unspecced
hasAttr(key: string): boolean;

isRecordInUse(): boolean;
_initRecordCreateOptions(options: any): { [key: string]: unknown };

// new
Expand Down
2 changes: 1 addition & 1 deletion ember-data-types/q/relationship-record-data.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type BelongsToRelationship from '@ember-data/record-data/-private/relationships/state/belongs-to';
import type { RecordDataStoreWrapper } from '@ember-data/store/-private';

import type { CollectionResourceRelationship, SingleResourceRelationship } from './ember-data-json-api';
import type { RecordIdentifier, StableRecordIdentifier } from './identifier';
import type { RecordData } from './record-data';
import type { RecordDataStoreWrapper } from './record-data-store-wrapper';

export interface DefaultSingleResourceRelationship extends SingleResourceRelationship {
_relationship: BelongsToRelationship;
Expand Down
Loading

0 comments on commit 8e6b742

Please sign in to comment.