API Docs for: 5.4.0-alpha.27+524e8e8a
Show:

File: ../packages/store/src/index.ts

/**
 * <p align="center">
 *   <img
 *     class="project-logo"
 *     src="https://raw.githubusercontent.com/emberjs/data/4612c9354e4c54d53327ec2cf21955075ce21294/ember-data-logo-light.svg#gh-light-mode-only"
 *     alt="EmberData Store"
 *     width="240px"
 *     title="EmberData Store"
 *     />
 * </p>
 *
 * This package provides [*Ember***Data**](https://github.com/emberjs/data/)'s `Store` class.
 *
 * A [Store](https://api.emberjs.com/ember-data/release/classes/Store) coordinates interaction between your application, a [Cache](https://api.emberjs.com/ember-data/release/classes/%3CInterface%3E%20Cache),
 * and sources of data (such as your API or a local persistence layer) accessed via a [RequestManager](https://github.com/emberjs/data/tree/main/packages/request).
 *
 * Optionally, a Store can be configured to hydrate the response data into rich presentation classes.
 *
 * ## Installation
 *
 * If you have installed `ember-data` then you already have this package installed.
 * Otherwise you can install it using your javascript package manager of choice.
 * For instance with [pnpm](https://pnpm.io/)
 *
 * ```
 * pnpm add @ember-data/store
 * ```
 *
 * After installing you will want to configure your first `Store`. Read more below
 * for how to create and configure stores for your application.
 *
 *
 * ## 🔨 Creating A Store
 *
 * To use a `Store` we will need to do few things: add a [Cache](https://api.emberjs.com/ember-data/release/classes/%3CInterface%3E%20Cache)
 * to store data **in-memory**, add a [Handler](https://api.emberjs.com/ember-data/release/classes/%3CInterface%3E%20Cache) to fetch data from a source,
 * and implement `instantiateRecord` to tell the store how to display the data for individual resources.
 *
 * > **Note**
 * > If you are using the package `ember-data` then a JSON:API cache, RequestManager, LegacyNetworkHandler,
 * > and `instantiateRecord` are configured for you by default.
 *
 * ### Configuring A Cache
 *
 * To start, let's install a [JSON:API](https://jsonapi.org/) cache. If your app uses `GraphQL` or `REST` other
 * caches may better fit your data. You can author your own cache by creating one that
 * conforms to the [spec](https://api.emberjs.com/ember-data/release/classes/%3CInterface%3E%20Cache).
 *
 * The package `@ember-data/json-api` provides a [JSON:API](https://jsonapi.org/) cache we can use.
 * After installing it, we can configure the store to use this cache.
 *
 * ```js
 * import Store from '@ember-data/store';
 * import Cache from '@ember-data/json-api';
 *
 * class extends Store {
 *   createCache(storeWrapper) {
 *     return new Cache(storeWrapper);
 *   }
 * }
 * ```
 *
 * Now that we have a `cache` let's setup something to handle fetching
 * and saving data via our API.
 *
 * > **Note**
 * > The `ember-data` package automatically includes and configures
 * > the `@ember-data/json-api` cache for you.
 *
 * ### Handling Requests
 *
 * When *Ember***Data** needs to fetch or save data it will pass that request to your application's `RequestManager` for fulfillment. How this fulfillment occurs (in-memory, device storage, via single or multiple API requests, etc.) is then up to the registered request handlers.
 *
 * To start, let's install the `RequestManager` from `@ember-data/request` and the basic `Fetch` handler from ``@ember-data/request/fetch`.
 *
 * > **Note**
 * > If your app uses `GraphQL`, `REST` or different conventions for `JSON:API` than your cache expects, other handlers may better fit your data. You can author your own handler by creating one that conforms to the [handler interface](https://github.com/emberjs/data/tree/main/packages/request#handling-requests).
 *
 * ```ts
 * import Store from '@ember-data/store';
 * import RequestManager from '@ember-data/request';
 * import Fetch from '@ember-data/request/fetch';
 *
 * export default class extends Store {
 *   constructor() {
 *     super(...arguments);
 *     this.requestManager = new RequestManager();
 *     this.requestManager.use([Fetch]);
 *   }
 * }
 * ```
 *
 * **Using RequestManager as a Service**
 *
 * Alternatively if you have configured the `RequestManager` to be a service you may re-use it.
 *
 * *app/services/request.js*
 * ```ts
 * import RequestManager from '@ember-data/request';
 * import Fetch from '@ember-data/request/fetch';
 *
 * export default class extends RequestManager {
 *   constructor(createArgs) {
 *     super(createArgs);
 *     this.use([Fetch]);
 *   }
 * }
 * ```
 *
 * *app/services/store.js*
 * ```ts
 * import Store from '@ember-data/store';
 * import { service } from '@ember/service';
 *
 * export default class extends Store {
 *   @service('request') requestManager
 * }
 * ```
 *
 *
 * ### Presenting Data from the Cache
 *
 * Now that we have a source and a cach for our data, we need to configure how
 * the Store delivers that data back to our application. We do this via the hook
 * [instantiateRecord](https://api.emberjs.com/ember-data/release/classes/Store/methods/instantiateRecord%20(hook)?anchor=instantiateRecord%20(hook)),
 * which allows us to transform the data for a resource before handing it to the application.
 *
 * A naive way to present the data would be to return it as JSON. Typically instead
 * this hook will be used to add reactivity and make each unique resource a singleton,
 * ensuring that if the cache updates our presented data will reflect the new state.
 *
 * Below is an example of using the hooks `instantiateRecord` and a `teardownRecord`
 * to provide minimal read-only reactive state for simple resources.
 *
 * ```ts
 * import Store, { recordIdentifierFor } from '@ember-data/store';
 * import { TrackedObject } from 'tracked-built-ins';
 *
 * class extends Store {
 *   instantiateRecord(identifier) {
 *     const { cache, notifications } = this;
 *
 *     // create a TrackedObject with our attributes, id and type
 *     const record = new TrackedObject(Object.assign({}, cache.peek(identifier)));
 *     record.type = identifier.type;
 *     record.id = identifier.id;
 *
 *     notifications.subscribe(identifier, (_, change) => {
 *       if (change === 'attributes') {
 *         Object.assign(record, cache.peek(identifier));
 *       }
 *     });
 *
 *     return record;
 *   }
 * }
 * ```
 *
 * Because `instantiateRecord` is opaque to the nature of the record, an implementation
 * can be anything from a fairly simple object to a robust proxy that intelligently links
 * together associated records through relationships.
 *
 * This also enables creating a record that separates `edit` flows from `create` flows
 * entirely. A record class might choose to implement a `checkout`method that gives access
 * to an editable instance while the primary record continues to be read-only and reflect
 * only persisted (non-mutated) state.
 *
 * Typically you will choose an existing record implementation such as `@ember-data/model`
 * for your application.
 *
 * Because of the boundaries around instantiation and the cache, record implementations
 * should be capable of interop both with each other and with any `Cache`. Due to this,
 * if needed an application can utilize multiple record implementations and multiple cache
 * implementations either to support enhanced features for only a subset of records or to
 * be able to incrementally migrate from one record/cache to another record or cache.
 *
 * > **Note**
 * > The `ember-data` package automatically includes the `@ember-data/model`
 * > package and configures it for you.
 *
 * @module @ember-data/store
 * @main @ember-data/store
 */

export {
  Store as default,
  CacheHandler,
  type LifetimesService,
  setIdentifierGenerationMethod,
  setIdentifierUpdateMethod,
  setIdentifierForgetMethod,
  setIdentifierResetMethod,
  recordIdentifierFor,
  storeFor,
} from './-private';