@ember-data/store 4.12.0-alpha.2 → 4.12.0-alpha.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (C) 2017-2022 Ember.js contributors
3
+ Copyright (C) 2017-2023 Ember.js contributors
4
4
  Portions Copyright (C) 2011-2017 Tilde, Inc. and contributors.
5
5
  Portions Copyright (C) 2011 LivingSocial Inc.
6
6
 
package/README.md CHANGED
@@ -1,31 +1,189 @@
1
- @ember-data/store
2
- ==============================================================================
1
+ <p align="center">
2
+ <img
3
+ class="project-logo"
4
+ src="./ember-data-logo-dark.svg#gh-dark-mode-only"
5
+ alt="EmberData Store"
6
+ width="240px"
7
+ title="EmberData Store"
8
+ />
9
+ <img
10
+ class="project-logo"
11
+ src="./ember-data-logo-light.svg#gh-light-mode-only"
12
+ alt="EmberData Store"
13
+ width="240px"
14
+ title="EmberData Store"
15
+ />
16
+ </p>
3
17
 
4
- [Short description of the addon.]
18
+ <p align="center">⚡️ The lightweight reactive data library for JavaScript applications</p>
5
19
 
20
+ This package provides [*Ember***Data**](https://github.com/emberjs/data/)'s `Store` class.
6
21
 
7
- Compatibility
8
- ------------------------------------------------------------------------------
22
+ The `Store` coordinates interaction between your application, a [Cache](https://api.emberjs.com/ember-data/release/classes/%3CInterface%3E%20Cache),
23
+ 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).
9
24
 
10
- * Ember.js v3.4 or above
11
- * Ember CLI v2.13 or above
25
+ ```mermaid
26
+ flowchart LR
27
+ A[fa:fa-terminal App] ===> D{fa:fa-code-fork Store}
28
+ B{{fa:fa-sitemap RequestManager}} <--> C[(fa:fa-database Source)]
29
+ D <--> E[(fa:fa-archive Cache)]
30
+ D <--> B
31
+ click B href "https://github.com/emberjs/data/tree/main/packages/request" "Go to @ember-data/request" _blank
32
+ click E href "https://github.com/emberjs/data/tree/main/packages/json-api" "Go to @ember-data/json-api" _blank
33
+ style B color:#58a6ff;
34
+ style E color:#58a6ff;
35
+ ```
36
+
37
+ Optionally, the Store can be configured to hydrate the response data into rich presentation classes.
38
+
39
+ ```mermaid
40
+ flowchart LR
41
+ A[fa:fa-terminal App] --- B(Model)
42
+ A === C{fa:fa-code-fork Store}
43
+ B --- C
44
+ click B href "https://github.com/emberjs/data/tree/main/packages/model" "Go to @ember-data/model" _blank
45
+ style B color:#58a6ff;
46
+ ```
47
+
48
+ ## Installation
49
+
50
+ Install using your javascript package manager of choice. For instance with [pnpm](https://pnpm.io/)
51
+
52
+ ```
53
+ pnpm add @ember-data/store
54
+ ```
55
+
56
+ After installing you will want to configure your first `Store`. Read more below for how to create and configure stores for your application.
57
+
58
+
59
+ ## 🔨 Creating A Store
60
+
61
+ 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://github.com/emberjs/data/tree/main/packages/request#handling-requests) to fetch data from a source, and implement `instantiateRecord` to tell the store how to display the data for individual resources.
62
+
63
+ > **Note** If you are using the package `ember-data` then a `JSON:API` cache and `instantiateRecord` are configured for you by default.
64
+
65
+ ### Configuring A Cache
66
+
67
+ 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).
68
+
69
+ The package [@ember-data/json-api](https://github.com/emberjs/data/tree/main/packages/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.
70
+
71
+ ```js
72
+ import Store from '@ember-data/store';
73
+ import Cache from '@ember-data/json-api';
74
+
75
+ class extends Store {
76
+ createCache(storeWrapper) {
77
+ return new Cache(storeWrapper);
78
+ }
79
+ }
80
+ ```
81
+
82
+ Now that we have a `cache` let's setup something to handle fetching and saving data via our API.
12
83
 
84
+ > **Note** The `ember-data` package automatically includes and configures the `@ember-data/json-api` cache for you.
13
85
 
14
- Installation
15
- ------------------------------------------------------------------------------
86
+ ### Handling Requests
16
87
 
88
+ 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.
89
+
90
+ To start, let's install the `FetchManager` from `@ember-data/request` and the basic `Fetch` handler from ``@ember-data/request/fetch`.
91
+
92
+ > **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).
93
+
94
+ ```ts
95
+ import Store, { CacheHandler } from '@ember-data/store';
96
+ import RequestManager from '@ember-data/request';
97
+ import Fetch from '@ember-data/request/fetch';
98
+
99
+ export default class extends Store {
100
+ constructor() {
101
+ super(...arguments);
102
+ this.requestManager = new RequestManager();
103
+ this.requestManager.use([Fetch]);
104
+ this.requestManager.useCache(CacheHandler);
105
+ }
106
+ }
17
107
  ```
18
- ember install @ember-data/store
108
+
109
+ **Using RequestManager as a Service**
110
+
111
+ Alternatively if you have configured the `RequestManager` to be a service you may re-use it.
112
+
113
+ *app/services/request.js*
114
+ ```ts
115
+ import RequestManager from '@ember-data/request';
116
+ import { CacheHandler } from '@ember-data/store';
117
+ import Fetch from '@ember-data/request/fetch';
118
+
119
+ export default class extends RequestManager {
120
+ constructor(createArgs) {
121
+ super(createArgs);
122
+ this.use([Fetch]);
123
+ this.useCache(CacheHandler);
124
+ }
125
+ }
126
+ ```
127
+
128
+ *app/services/store.js*
129
+ ```ts
130
+ import Store from '@ember-data/store';
131
+ import { service } from '@ember/service';
132
+
133
+ export default class extends Store {
134
+ @service('request') requestManager
135
+ }
19
136
  ```
20
137
 
138
+ ### Presenting Data from the Cache
139
+
140
+ 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)),
141
+ which allows us to transform the data for a resource before handing it to the application.
142
+
143
+ 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.
144
+
145
+ Below is an example of using the hooks `instantiateRecord` and a `teardownRecord` to provide minimal read-only reactive state for simple resources.
146
+
147
+ ```ts
148
+ import Store, { recordIdentifierFor } from '@ember-data/store';
149
+ import { TrackedObject } from 'tracked-built-ins';
150
+
151
+ class extends Store {
152
+ instantiateRecord(identifier) {
153
+ const { cache, notifications } = this;
154
+
155
+ // create a TrackedObject with our attributes, id and type
156
+ const record = new TrackedObject(Object.assign({}, cache.peek(identifier)));
157
+ record.type = identifier.type;
158
+ record.id = identifier.id;
159
+
160
+ // update the TrackedObject whenever attributes change
161
+ const token = notifications.subscribe(identifier, (_, change) => {
162
+ if (change === 'attributes') {
163
+ Object.assign(record, cache.peek(identifier));
164
+ }
165
+ });
166
+
167
+ record.destroy = () => {
168
+ this.notifications.unsubscribe(token);
169
+ };
170
+
171
+ return record;
172
+ }
173
+
174
+ teardownRecord(record: FakeRecord) {
175
+ record.destroy();
176
+ }
177
+ }
178
+ ```
21
179
 
22
- Usage
23
- ------------------------------------------------------------------------------
180
+ 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.
24
181
 
25
- [Longer description of how to use the addon in apps.]
182
+ 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.
26
183
 
184
+ Typically you will choose an existing record implementation such as `@ember-data/model` for your application.
27
185
 
28
- License
29
- ------------------------------------------------------------------------------
186
+ 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.
30
187
 
31
- This project is licensed under the [MIT License](LICENSE.md).
188
+ > **Note:** The `ember-data` package automatically includes the `@ember-data/model`
189
+ > package and configures it for you.
package/addon/-private.js CHANGED
@@ -1 +1 @@
1
- export { C as AdapterPopulatedRecordArray, j as IDENTIFIER_ARRAY_TAG, I as IdentifierArray, M as MUTATE, I as RecordArray, R as RecordArrayManager, h as SOURCE, a as Snapshot, l as SnapshotRecordArray, S as Store, f as coerceId, k as fastPush, i as isStableIdentifier, n as normalizeModelName, g as notifyArray, m as recordDataFor, r as recordIdentifierFor, o as removeRecordDataFor, d as setIdentifierForgetMethod, b as setIdentifierGenerationMethod, e as setIdentifierResetMethod, c as setIdentifierUpdateMethod, s as storeFor } from "./index-6511184b";
1
+ export { f as AdapterPopulatedRecordArray, C as CacheHandler, j as IDENTIFIER_ARRAY_TAG, I as IdentifierArray, M as MUTATE, I as RecordArray, R as RecordArrayManager, h as SOURCE, S as Store, _ as _clearCaches, e as coerceId, k as fastPush, i as isStableIdentifier, n as normalizeModelName, g as notifyArray, p as peekCache, r as recordIdentifierFor, l as removeRecordDataFor, c as setIdentifierForgetMethod, a as setIdentifierGenerationMethod, d as setIdentifierResetMethod, b as setIdentifierUpdateMethod, s as storeFor } from "./index-8b77b852";