@ember-data/store 4.12.0-beta.6 → 4.12.0-beta.8
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 +1 -1
- package/README.md +47 -40
- package/addon/-private.js +1 -1
- package/addon/{index-35424a6b.js → index-0d52354f.js} +267 -217
- package/addon/index-0d52354f.js.map +1 -0
- package/addon/index.js +1 -1
- package/addon-main.js +1 -1
- package/ember-data-logo-dark.svg +12 -0
- package/ember-data-logo-light.svg +12 -0
- package/package.json +15 -9
- package/addon/index-35424a6b.js.map +0 -1
package/LICENSE.md
CHANGED
package/README.md
CHANGED
|
@@ -80,66 +80,64 @@ class extends Store {
|
|
|
80
80
|
|
|
81
81
|
Now that we have a `cache` let's setup something to handle fetching and saving data via our API.
|
|
82
82
|
|
|
83
|
-
> Note
|
|
83
|
+
> **Note** [1] the cache from `@ember-data/json-api` is a special cache: if the package is present the `createCache` hook will automatically do the above wiring if the hook is not implemented. We still recommend implementing the hook.
|
|
84
84
|
>
|
|
85
|
-
> Note
|
|
85
|
+
> **Note** [2] The `ember-data` package automatically includes the `@ember-data/json-api` cache for you.
|
|
86
86
|
|
|
87
|
-
###
|
|
87
|
+
### Handling Requests
|
|
88
88
|
|
|
89
|
-
When *Ember***Data** needs to fetch or save data it will pass that request to your application's `
|
|
89
|
+
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.
|
|
90
90
|
|
|
91
|
-
To start, let's install
|
|
91
|
+
To start, let's install the `FetchManager` from `@ember-data/request` and the basic `Fetch` handler from ``@ember-data/request/fetch`.
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
> **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).
|
|
94
94
|
|
|
95
|
-
```
|
|
95
|
+
```ts
|
|
96
96
|
import Store from '@ember-data/store';
|
|
97
|
-
import
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
97
|
+
import RequestManager from '@ember-data/request';
|
|
98
|
+
import Fetch from '@ember-data/request/fetch';
|
|
99
|
+
|
|
100
|
+
export default class extends Store {
|
|
101
|
+
constructor() {
|
|
102
|
+
super(...arguments);
|
|
103
|
+
this.requestManager = new RequestManager();
|
|
104
|
+
this.requestManager.use([Fetch]);
|
|
104
105
|
}
|
|
105
106
|
}
|
|
106
107
|
```
|
|
107
108
|
|
|
108
|
-
|
|
109
|
+
**Using RequestManager as a Service**
|
|
109
110
|
|
|
110
|
-
|
|
111
|
+
Alternatively if you have configured the `RequestManager` to be a service you may re-use it.
|
|
111
112
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
import
|
|
116
|
-
import Adapter from '@ember-data/adapter/json-api';
|
|
117
|
-
import { getOwner, setOwner } from '@ember/application';
|
|
113
|
+
*app/services/request.js*
|
|
114
|
+
```ts
|
|
115
|
+
import RequestManager from '@ember-data/request';
|
|
116
|
+
import Fetch from '@ember-data/request/fetch';
|
|
118
117
|
|
|
119
|
-
class extends
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
let adapter = this.#adapter;
|
|
124
|
-
if (!adapter) {
|
|
125
|
-
const owner = getOwner(this);
|
|
126
|
-
adapter = new Adapter();
|
|
127
|
-
setOwner(adapter, owner);
|
|
128
|
-
this.#adapter = adapter;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return adapter;
|
|
118
|
+
export default class extends RequestManager {
|
|
119
|
+
constructor(createArgs) {
|
|
120
|
+
super(createArgs);
|
|
121
|
+
this.use([Fetch]);
|
|
132
122
|
}
|
|
133
123
|
}
|
|
134
124
|
```
|
|
135
125
|
|
|
136
|
-
|
|
126
|
+
*app/services/store.js*
|
|
127
|
+
```ts
|
|
128
|
+
import Store from '@ember-data/store';
|
|
129
|
+
import { service } from '@ember/service';
|
|
130
|
+
|
|
131
|
+
export default class extends Store {
|
|
132
|
+
@service('request') requestManager
|
|
133
|
+
}
|
|
134
|
+
```
|
|
137
135
|
|
|
138
136
|
### Presenting Data from the Cache
|
|
139
137
|
|
|
140
138
|
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`, which allows us to transform the data for a resource before handing it to the application.
|
|
141
139
|
|
|
142
|
-
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
|
|
140
|
+
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.
|
|
143
141
|
|
|
144
142
|
Below is an example of using the hooks `instantiateRecord` and a `teardownRecord` to provide minimal read-only reactive state for simple resources.
|
|
145
143
|
|
|
@@ -156,25 +154,34 @@ class extends Store {
|
|
|
156
154
|
record.type = identifier.type;
|
|
157
155
|
record.id = identifier.id;
|
|
158
156
|
|
|
159
|
-
|
|
157
|
+
// update the TrackedObject whenever attributes change
|
|
158
|
+
const token = notifications.subscribe(identifier, (_, change) => {
|
|
160
159
|
if (change === 'attributes') {
|
|
161
160
|
Object.assign(record, cache.peek(identifier));
|
|
162
161
|
}
|
|
163
162
|
});
|
|
164
163
|
|
|
164
|
+
record.destroy = () => {
|
|
165
|
+
this.notifications.unsubscribe(token);
|
|
166
|
+
};
|
|
167
|
+
|
|
165
168
|
return record;
|
|
166
169
|
}
|
|
170
|
+
|
|
171
|
+
teardownRecord(record: FakeRecord) {
|
|
172
|
+
record.destroy();
|
|
173
|
+
}
|
|
167
174
|
}
|
|
168
175
|
```
|
|
169
176
|
|
|
170
177
|
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.
|
|
171
178
|
|
|
172
|
-
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.
|
|
179
|
+
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.
|
|
173
180
|
|
|
174
181
|
Typically you will choose an existing record implementation such as `@ember-data/model` for your application.
|
|
175
182
|
|
|
176
183
|
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.
|
|
177
184
|
|
|
178
|
-
> Note: [1] `@ember-data/model` is a special record implementation: if the package is present the `instantiateRecord` hook will automatically do the above wiring if the hook is not implemented.
|
|
185
|
+
> Note: [1] `@ember-data/model` is a special record implementation: currently, if the package is present the `instantiateRecord` hook will automatically do the above wiring if the hook is not implemented.
|
|
179
186
|
>
|
|
180
187
|
> Note: [2] The `ember-data` package automatically includes the `@ember-data/model` implementation for you.
|
package/addon/-private.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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-
|
|
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-0d52354f";
|