@ember-data/store 4.4.0 → 4.5.0-alpha.2
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/addon/-private/system/core-store.ts +136 -147
- package/addon/-private/system/ds-model-store.ts +1 -10
- package/addon/-private/system/fetch-manager.ts +48 -21
- package/addon/-private/system/model/internal-model.ts +263 -192
- package/addon/-private/system/model/states.js +5 -41
- package/addon/-private/system/{promise-proxies.js → promise-proxies.ts} +31 -21
- package/addon/-private/system/promise-proxy-base.js +7 -0
- package/addon/-private/system/{record-array-manager.js → record-array-manager.ts} +87 -60
- package/addon/-private/system/record-arrays/adapter-populated-record-array.ts +129 -0
- package/addon/-private/system/record-arrays/{record-array.js → record-array.ts} +96 -75
- package/addon/-private/system/record-data-for.ts +2 -0
- package/addon/-private/system/references/belongs-to.ts +3 -2
- package/addon/-private/system/references/has-many.ts +4 -2
- package/addon/-private/system/schema-definition-service.ts +2 -2
- package/addon/-private/system/snapshot-record-array.ts +12 -11
- package/addon/-private/system/snapshot.ts +24 -7
- package/addon/-private/system/store/common.js +24 -1
- package/addon/-private/system/store/finders.js +53 -5
- package/addon/-private/system/store/internal-model-factory.ts +8 -7
- package/addon/-private/system/store/record-data-store-wrapper.ts +7 -2
- package/addon/-private/system/store/serializer-response.ts +85 -0
- package/addon/-private/ts-interfaces/ds-model.ts +15 -7
- package/addon/-private/ts-interfaces/ember-data-json-api.ts +3 -0
- package/addon/-private/ts-interfaces/minimum-adapter-interface.ts +19 -20
- package/addon/-private/ts-interfaces/minimum-serializer-interface.ts +27 -6
- package/addon/-private/ts-interfaces/record-data.ts +4 -1
- package/addon/-private/ts-interfaces/record-instance.ts +3 -1
- package/addon/-private/ts-interfaces/store.ts +1 -0
- package/addon/-private/utils/promise-record.ts +3 -3
- package/index.js +3 -0
- package/package.json +7 -6
- package/addon/-private/system/record-arrays/adapter-populated-record-array.js +0 -95
- package/addon/-private/system/store/serializer-response.js +0 -71
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import type NativeArray from '@ember/array/-private/native-array';
|
|
2
|
+
import { assert } from '@ember/debug';
|
|
3
|
+
|
|
4
|
+
import type { PromiseArray, RecordArrayManager } from 'ember-data/-private';
|
|
5
|
+
|
|
6
|
+
import type { CollectionResourceDocument, Links, Meta, PaginationLinks } from '../../ts-interfaces/ember-data-json-api';
|
|
7
|
+
import type { StableRecordIdentifier } from '../../ts-interfaces/identifier';
|
|
8
|
+
import type { RecordInstance } from '../../ts-interfaces/record-instance';
|
|
9
|
+
import type { FindOptions } from '../../ts-interfaces/store';
|
|
10
|
+
import type { Dict } from '../../ts-interfaces/utils';
|
|
11
|
+
import type CoreStore from '../core-store';
|
|
12
|
+
import { promiseArray } from '../promise-proxies';
|
|
13
|
+
import SnapshotRecordArray from '../snapshot-record-array';
|
|
14
|
+
import RecordArray from './record-array';
|
|
15
|
+
|
|
16
|
+
export interface AdapterPopulatedRecordArrayCreateArgs {
|
|
17
|
+
modelName: string;
|
|
18
|
+
store: CoreStore;
|
|
19
|
+
manager: RecordArrayManager;
|
|
20
|
+
content: NativeArray<StableRecordIdentifier>;
|
|
21
|
+
isLoaded: boolean;
|
|
22
|
+
query?: Dict<unknown>;
|
|
23
|
+
meta?: Meta;
|
|
24
|
+
links?: Links | PaginationLinks | null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
@module @ember-data/store
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
Represents an ordered list of records whose order and membership is
|
|
33
|
+
determined by the adapter. For example, a query sent to the adapter
|
|
34
|
+
may trigger a search on the server, whose results would be loaded
|
|
35
|
+
into an instance of the `AdapterPopulatedRecordArray`.
|
|
36
|
+
|
|
37
|
+
This class should not be imported and instantiated by consuming applications.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
If you want to update the array and get the latest records from the
|
|
42
|
+
adapter, you can invoke [`update()`](AdapterPopulatedRecordArray/methods/update?anchor=update):
|
|
43
|
+
|
|
44
|
+
Example
|
|
45
|
+
|
|
46
|
+
```javascript
|
|
47
|
+
// GET /users?isAdmin=true
|
|
48
|
+
store.query('user', { isAdmin: true }).then(function(admins) {
|
|
49
|
+
|
|
50
|
+
admins.then(function() {
|
|
51
|
+
console.log(admins.get("length")); // 42
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// somewhere later in the app code, when new admins have been created
|
|
55
|
+
// in the meantime
|
|
56
|
+
//
|
|
57
|
+
// GET /users?isAdmin=true
|
|
58
|
+
admins.update().then(function() {
|
|
59
|
+
admins.get('isUpdating'); // false
|
|
60
|
+
console.log(admins.get("length")); // 123
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
admins.get('isUpdating'); // true
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
@class AdapterPopulatedRecordArray
|
|
68
|
+
@public
|
|
69
|
+
@extends RecordArray
|
|
70
|
+
*/
|
|
71
|
+
export default class AdapterPopulatedRecordArray extends RecordArray {
|
|
72
|
+
declare links: Links | PaginationLinks | null;
|
|
73
|
+
declare meta: Dict<unknown> | null;
|
|
74
|
+
declare query: Dict<unknown> | null;
|
|
75
|
+
|
|
76
|
+
init(props?: AdapterPopulatedRecordArrayCreateArgs) {
|
|
77
|
+
assert(`Cannot initialize AdapterPopulatedRecordArray with isUpdating`, !props || !('isUpdating' in props));
|
|
78
|
+
super.init();
|
|
79
|
+
this.query = this.query || null;
|
|
80
|
+
this.links = this.links || null;
|
|
81
|
+
this.meta = this.meta || null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
replace() {
|
|
85
|
+
throw new Error(`The result of a server query (on ${this.modelName}) is immutable.`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
_update(): PromiseArray<RecordInstance, AdapterPopulatedRecordArray> {
|
|
89
|
+
const { store, query } = this;
|
|
90
|
+
|
|
91
|
+
// TODO save options from initial request?
|
|
92
|
+
return promiseArray(store._query(this.modelName, query, this, {}));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
_setObjects(identifiers: StableRecordIdentifier[], payload: CollectionResourceDocument) {
|
|
96
|
+
// TODO: initial load should not cause change events at all, only
|
|
97
|
+
// subsequent. This requires changing the public api of adapter.query, but
|
|
98
|
+
// hopefully we can do that soon.
|
|
99
|
+
this.content.setObjects(identifiers);
|
|
100
|
+
|
|
101
|
+
this.setProperties({
|
|
102
|
+
isLoaded: true,
|
|
103
|
+
isUpdating: false,
|
|
104
|
+
// TODO this assign kills the root reference but a deep-copy would be required
|
|
105
|
+
// for both meta and links to actually not be by-ref. We whould likely change
|
|
106
|
+
// this to a dev-only deep-freeze.
|
|
107
|
+
meta: Object.assign({}, payload.meta),
|
|
108
|
+
links: Object.assign({}, payload.links),
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
this.manager._associateWithRecordArray(identifiers, this);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
_createSnapshot(options: FindOptions) {
|
|
115
|
+
// this is private for users, but public for ember-data internals
|
|
116
|
+
// meta will only be present for an AdapterPopulatedRecordArray
|
|
117
|
+
return new SnapshotRecordArray(this, this.meta, options);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
@method _setIdentifiers
|
|
122
|
+
@param {StableRecordIdentifier[]} identifiers
|
|
123
|
+
@param {Object} payload normalized payload
|
|
124
|
+
@private
|
|
125
|
+
*/
|
|
126
|
+
_setIdentifiers(identifiers: StableRecordIdentifier[], payload: CollectionResourceDocument): void {
|
|
127
|
+
this._setObjects(identifiers, payload);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -1,19 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
2
|
@module @ember-data/store
|
|
3
3
|
*/
|
|
4
|
+
import type NativeArray from '@ember/array/-private/native-array';
|
|
4
5
|
import ArrayProxy from '@ember/array/proxy';
|
|
6
|
+
import { assert } from '@ember/debug';
|
|
5
7
|
import { computed, get, set } from '@ember/object';
|
|
8
|
+
import { tracked } from '@glimmer/tracking';
|
|
6
9
|
|
|
7
10
|
import { Promise } from 'rsvp';
|
|
8
11
|
|
|
9
|
-
import {
|
|
12
|
+
import type { RecordArrayManager, Snapshot } from 'ember-data/-private';
|
|
13
|
+
|
|
14
|
+
import type { StableRecordIdentifier } from '../../ts-interfaces/identifier';
|
|
15
|
+
import type { RecordInstance } from '../../ts-interfaces/record-instance';
|
|
16
|
+
import type { FindOptions } from '../../ts-interfaces/store';
|
|
17
|
+
import type CoreStore from '../core-store';
|
|
18
|
+
import type { PromiseArray } from '../promise-proxies';
|
|
19
|
+
import { promiseArray } from '../promise-proxies';
|
|
10
20
|
import SnapshotRecordArray from '../snapshot-record-array';
|
|
11
21
|
import { internalModelFactoryFor } from '../store/internal-model-factory';
|
|
12
22
|
|
|
13
|
-
function recordForIdentifier(store, identifier) {
|
|
23
|
+
function recordForIdentifier(store: CoreStore, identifier: StableRecordIdentifier): RecordInstance {
|
|
14
24
|
return internalModelFactoryFor(store).lookup(identifier).getRecord();
|
|
15
25
|
}
|
|
16
26
|
|
|
27
|
+
export interface RecordArrayCreateArgs {
|
|
28
|
+
modelName: string;
|
|
29
|
+
store: CoreStore;
|
|
30
|
+
manager: RecordArrayManager;
|
|
31
|
+
content: NativeArray<StableRecordIdentifier>;
|
|
32
|
+
isLoaded: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
17
35
|
/**
|
|
18
36
|
A record array is an array that contains records of a certain modelName. The record
|
|
19
37
|
array materializes records as needed when they are retrieved for the first
|
|
@@ -27,24 +45,21 @@ function recordForIdentifier(store, identifier) {
|
|
|
27
45
|
@public
|
|
28
46
|
@extends Ember.ArrayProxy
|
|
29
47
|
*/
|
|
48
|
+
export default class RecordArray extends ArrayProxy<StableRecordIdentifier, RecordInstance> {
|
|
49
|
+
/**
|
|
50
|
+
The array of client ids backing the record array. When a
|
|
51
|
+
record is requested from the record array, the record
|
|
52
|
+
for the client id at the same index is materialized, if
|
|
53
|
+
necessary, by the store.
|
|
30
54
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
necessary, by the store.
|
|
40
|
-
|
|
41
|
-
@property content
|
|
42
|
-
@private
|
|
43
|
-
@type Ember.Array
|
|
44
|
-
*/
|
|
45
|
-
this.set('content', this.content || null);
|
|
46
|
-
|
|
47
|
-
/**
|
|
55
|
+
@property content
|
|
56
|
+
@private
|
|
57
|
+
@type Ember.Array
|
|
58
|
+
*/
|
|
59
|
+
declare content: NativeArray<StableRecordIdentifier>;
|
|
60
|
+
declare _getDeprecatedEventedInfo: () => string;
|
|
61
|
+
declare modelName: string;
|
|
62
|
+
/**
|
|
48
63
|
The flag to signal a `RecordArray` is finished loading data.
|
|
49
64
|
|
|
50
65
|
Example
|
|
@@ -57,42 +72,49 @@ let RecordArray = ArrayProxy.extend({
|
|
|
57
72
|
@property isLoaded
|
|
58
73
|
@public
|
|
59
74
|
@type Boolean
|
|
75
|
+
*/
|
|
76
|
+
declare isLoaded: boolean;
|
|
77
|
+
/**
|
|
78
|
+
The store that created this record array.
|
|
79
|
+
|
|
80
|
+
@property store
|
|
81
|
+
@private
|
|
82
|
+
@type Store
|
|
60
83
|
*/
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
84
|
+
declare store: CoreStore;
|
|
85
|
+
declare _updatingPromise: PromiseArray<RecordInstance, RecordArray> | null;
|
|
86
|
+
declare manager: RecordArrayManager;
|
|
64
87
|
|
|
88
|
+
/**
|
|
89
|
+
The flag to signal a `RecordArray` is currently loading data.
|
|
65
90
|
Example
|
|
66
|
-
|
|
67
91
|
```javascript
|
|
68
92
|
let people = store.peekAll('person');
|
|
69
93
|
people.get('isUpdating'); // false
|
|
70
94
|
people.update();
|
|
71
95
|
people.get('isUpdating'); // true
|
|
72
96
|
```
|
|
73
|
-
|
|
74
97
|
@property isUpdating
|
|
75
98
|
@public
|
|
76
99
|
@type Boolean
|
|
77
|
-
|
|
78
|
-
|
|
100
|
+
*/
|
|
101
|
+
@tracked isUpdating: boolean = false;
|
|
79
102
|
|
|
80
|
-
|
|
81
|
-
|
|
103
|
+
init(props?: RecordArrayCreateArgs) {
|
|
104
|
+
assert(`Cannot initialize RecordArray with isUpdating`, !props || !('isUpdating' in props));
|
|
105
|
+
assert(`Cannot initialize RecordArray with isUpdating`, !props || !('_updatingPromise' in props));
|
|
106
|
+
super.init();
|
|
82
107
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
@type Store
|
|
86
|
-
*/
|
|
87
|
-
this.store = this.store || null;
|
|
108
|
+
// TODO can we get rid of this?
|
|
109
|
+
this.set('content', this.content || null);
|
|
88
110
|
this._updatingPromise = null;
|
|
89
|
-
}
|
|
111
|
+
}
|
|
90
112
|
|
|
91
113
|
replace() {
|
|
92
114
|
throw new Error(
|
|
93
115
|
`The result of a server query (for all ${this.modelName} types) is immutable. To modify contents, use toArray()`
|
|
94
116
|
);
|
|
95
|
-
}
|
|
117
|
+
}
|
|
96
118
|
|
|
97
119
|
/**
|
|
98
120
|
The modelClass represented by this record array.
|
|
@@ -101,12 +123,13 @@ let RecordArray = ArrayProxy.extend({
|
|
|
101
123
|
@public
|
|
102
124
|
@type {subclass of Model}
|
|
103
125
|
*/
|
|
104
|
-
|
|
126
|
+
@computed('modelName')
|
|
127
|
+
get type() {
|
|
105
128
|
if (!this.modelName) {
|
|
106
129
|
return null;
|
|
107
130
|
}
|
|
108
131
|
return this.store.modelFor(this.modelName);
|
|
109
|
-
}
|
|
132
|
+
}
|
|
110
133
|
|
|
111
134
|
/**
|
|
112
135
|
Retrieves an object from the content by index.
|
|
@@ -116,10 +139,10 @@ let RecordArray = ArrayProxy.extend({
|
|
|
116
139
|
@param {Number} index
|
|
117
140
|
@return {Model} record
|
|
118
141
|
*/
|
|
119
|
-
objectAtContent(index) {
|
|
142
|
+
objectAtContent(index: number): RecordInstance | undefined {
|
|
120
143
|
let identifier = get(this, 'content').objectAt(index);
|
|
121
144
|
return identifier ? recordForIdentifier(this.store, identifier) : undefined;
|
|
122
|
-
}
|
|
145
|
+
}
|
|
123
146
|
|
|
124
147
|
/**
|
|
125
148
|
Used to get the latest version of all of the records in this array
|
|
@@ -141,33 +164,34 @@ let RecordArray = ArrayProxy.extend({
|
|
|
141
164
|
@method update
|
|
142
165
|
@public
|
|
143
166
|
*/
|
|
144
|
-
update() {
|
|
145
|
-
if (
|
|
146
|
-
return this._updatingPromise
|
|
167
|
+
update(): PromiseArray<RecordInstance, RecordArray> {
|
|
168
|
+
if (this.isUpdating) {
|
|
169
|
+
return this._updatingPromise!;
|
|
147
170
|
}
|
|
148
171
|
|
|
149
|
-
this.
|
|
172
|
+
this.isUpdating = true;
|
|
150
173
|
|
|
151
|
-
let updatingPromise = this._update()
|
|
174
|
+
let updatingPromise = this._update();
|
|
175
|
+
updatingPromise.finally(() => {
|
|
152
176
|
this._updatingPromise = null;
|
|
153
|
-
if (this.
|
|
177
|
+
if (this.isDestroying || this.isDestroyed) {
|
|
154
178
|
return;
|
|
155
179
|
}
|
|
156
|
-
this.
|
|
180
|
+
this.isUpdating = false;
|
|
157
181
|
});
|
|
158
182
|
|
|
159
183
|
this._updatingPromise = updatingPromise;
|
|
160
184
|
|
|
161
185
|
return updatingPromise;
|
|
162
|
-
}
|
|
186
|
+
}
|
|
163
187
|
|
|
164
188
|
/*
|
|
165
189
|
Update this RecordArray and return a promise which resolves once the update
|
|
166
190
|
is finished.
|
|
167
191
|
*/
|
|
168
|
-
_update() {
|
|
192
|
+
_update(): PromiseArray<RecordInstance, RecordArray> {
|
|
169
193
|
return this.store.findAll(this.modelName, { reload: true });
|
|
170
|
-
}
|
|
194
|
+
}
|
|
171
195
|
|
|
172
196
|
/**
|
|
173
197
|
Saves all of the records in the `RecordArray`.
|
|
@@ -186,7 +210,7 @@ let RecordArray = ArrayProxy.extend({
|
|
|
186
210
|
@public
|
|
187
211
|
@return {PromiseArray} promise
|
|
188
212
|
*/
|
|
189
|
-
save() {
|
|
213
|
+
save(): PromiseArray<RecordInstance, RecordArray> {
|
|
190
214
|
let promiseLabel = `DS: RecordArray#save ${this.modelName}`;
|
|
191
215
|
let promise = Promise.all(this.invoke('save'), promiseLabel).then(
|
|
192
216
|
() => this,
|
|
@@ -194,8 +218,8 @@ let RecordArray = ArrayProxy.extend({
|
|
|
194
218
|
'DS: RecordArray#save return RecordArray'
|
|
195
219
|
);
|
|
196
220
|
|
|
197
|
-
return
|
|
198
|
-
}
|
|
221
|
+
return promiseArray<RecordInstance, RecordArray>(promise);
|
|
222
|
+
}
|
|
199
223
|
|
|
200
224
|
/**
|
|
201
225
|
@method _unregisterFromManager
|
|
@@ -203,7 +227,7 @@ let RecordArray = ArrayProxy.extend({
|
|
|
203
227
|
*/
|
|
204
228
|
_unregisterFromManager() {
|
|
205
229
|
this.manager.unregisterRecordArray(this);
|
|
206
|
-
}
|
|
230
|
+
}
|
|
207
231
|
|
|
208
232
|
willDestroy() {
|
|
209
233
|
this._unregisterFromManager();
|
|
@@ -215,33 +239,34 @@ let RecordArray = ArrayProxy.extend({
|
|
|
215
239
|
// * the exception being: if an dominator has a reference to this object,
|
|
216
240
|
// and must be informed to release e.g. e.g. removing itself from th
|
|
217
241
|
// recordArrayMananger
|
|
218
|
-
set(this, 'content', null);
|
|
242
|
+
set(this, 'content', null as unknown as NativeArray<StableRecordIdentifier>);
|
|
219
243
|
set(this, 'length', 0);
|
|
220
|
-
|
|
221
|
-
}
|
|
244
|
+
super.willDestroy();
|
|
245
|
+
}
|
|
222
246
|
|
|
223
247
|
/**
|
|
224
248
|
@method _createSnapshot
|
|
225
249
|
@private
|
|
226
250
|
*/
|
|
227
|
-
_createSnapshot(options) {
|
|
251
|
+
_createSnapshot(options: FindOptions) {
|
|
228
252
|
// this is private for users, but public for ember-data internals
|
|
229
|
-
|
|
230
|
-
|
|
253
|
+
// meta will only be present for an AdapterPopulatedRecordArray
|
|
254
|
+
return new SnapshotRecordArray(this, null, options);
|
|
255
|
+
}
|
|
231
256
|
|
|
232
257
|
/**
|
|
233
258
|
@method _dissociateFromOwnRecords
|
|
234
259
|
@internal
|
|
235
260
|
*/
|
|
236
261
|
_dissociateFromOwnRecords() {
|
|
237
|
-
this.
|
|
262
|
+
this.content.forEach((identifier) => {
|
|
238
263
|
let recordArrays = this.manager.getRecordArraysForIdentifier(identifier);
|
|
239
264
|
|
|
240
265
|
if (recordArrays) {
|
|
241
266
|
recordArrays.delete(this);
|
|
242
267
|
}
|
|
243
268
|
});
|
|
244
|
-
}
|
|
269
|
+
}
|
|
245
270
|
|
|
246
271
|
/**
|
|
247
272
|
Adds identifiers to the `RecordArray` without duplicates
|
|
@@ -250,9 +275,9 @@ let RecordArray = ArrayProxy.extend({
|
|
|
250
275
|
@internal
|
|
251
276
|
@param {StableRecordIdentifier[]} identifiers
|
|
252
277
|
*/
|
|
253
|
-
_pushIdentifiers(identifiers) {
|
|
254
|
-
|
|
255
|
-
}
|
|
278
|
+
_pushIdentifiers(identifiers: StableRecordIdentifier[]): void {
|
|
279
|
+
this.content.pushObjects(identifiers);
|
|
280
|
+
}
|
|
256
281
|
|
|
257
282
|
/**
|
|
258
283
|
Removes identifiers from the `RecordArray`.
|
|
@@ -261,19 +286,15 @@ let RecordArray = ArrayProxy.extend({
|
|
|
261
286
|
@internal
|
|
262
287
|
@param {StableRecordIdentifier[]} identifiers
|
|
263
288
|
*/
|
|
264
|
-
_removeIdentifiers(identifiers) {
|
|
265
|
-
|
|
266
|
-
}
|
|
289
|
+
_removeIdentifiers(identifiers: StableRecordIdentifier[]): void {
|
|
290
|
+
this.content.removeObjects(identifiers);
|
|
291
|
+
}
|
|
267
292
|
|
|
268
293
|
/**
|
|
269
294
|
@method _takeSnapshot
|
|
270
295
|
@internal
|
|
271
296
|
*/
|
|
272
|
-
_takeSnapshot() {
|
|
273
|
-
return
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
},
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
export default RecordArray;
|
|
297
|
+
_takeSnapshot(): Snapshot[] {
|
|
298
|
+
return this.content.map((identifier) => internalModelFactoryFor(this.store).lookup(identifier).createSnapshot());
|
|
299
|
+
}
|
|
300
|
+
}
|
|
@@ -3,6 +3,7 @@ import { DEBUG } from '@glimmer/env';
|
|
|
3
3
|
|
|
4
4
|
import type { StableRecordIdentifier } from '../ts-interfaces/identifier';
|
|
5
5
|
import type { RecordData } from '../ts-interfaces/record-data';
|
|
6
|
+
import type { RecordInstance } from '../ts-interfaces/record-instance';
|
|
6
7
|
import WeakCache from './weak-cache';
|
|
7
8
|
|
|
8
9
|
/*
|
|
@@ -40,6 +41,7 @@ export function removeRecordDataFor(identifier: StableRecordIdentifier): void {
|
|
|
40
41
|
|
|
41
42
|
export default function recordDataFor(instance: StableRecordIdentifier): RecordData | null;
|
|
42
43
|
export default function recordDataFor(instance: Instance): RecordData;
|
|
44
|
+
export default function recordDataFor(instance: RecordInstance): RecordData;
|
|
43
45
|
export default function recordDataFor(instance: object): null;
|
|
44
46
|
export default function recordDataFor(instance: Instance | object): RecordData | null {
|
|
45
47
|
if (RecordDataForIdentifierCache.has(instance as StableRecordIdentifier)) {
|
|
@@ -8,6 +8,7 @@ import { assertPolymorphicType } from '@ember-data/store/-debug';
|
|
|
8
8
|
|
|
9
9
|
import { SingleResourceDocument } from '../../ts-interfaces/ember-data-json-api';
|
|
10
10
|
import { StableRecordIdentifier } from '../../ts-interfaces/identifier';
|
|
11
|
+
import { RecordInstance } from '../../ts-interfaces/record-instance';
|
|
11
12
|
import CoreStore from '../core-store';
|
|
12
13
|
import { NotificationType, unsubscribe } from '../record-notification-manager';
|
|
13
14
|
import { internalModelFactoryFor, recordIdentifierFor } from '../store/internal-model-factory';
|
|
@@ -193,7 +194,7 @@ export default class BelongsToReference extends Reference {
|
|
|
193
194
|
@param {Object|Promise} objectOrPromise a promise that resolves to a JSONAPI document object describing the new value of this relationship.
|
|
194
195
|
@return {Promise<record>} A promise that resolves with the new value in this belongs-to relationship.
|
|
195
196
|
*/
|
|
196
|
-
async push(data: SingleResourceDocument | Promise<SingleResourceDocument>): Promise<
|
|
197
|
+
async push(data: SingleResourceDocument | Promise<SingleResourceDocument>): Promise<RecordInstance> {
|
|
197
198
|
const jsonApiDoc = await resolve(data);
|
|
198
199
|
let record = this.store.push(jsonApiDoc);
|
|
199
200
|
|
|
@@ -267,7 +268,7 @@ export default class BelongsToReference extends Reference {
|
|
|
267
268
|
@public
|
|
268
269
|
@return {Model} the record in this relationship
|
|
269
270
|
*/
|
|
270
|
-
value():
|
|
271
|
+
value(): RecordInstance | null {
|
|
271
272
|
let resource = this._resource();
|
|
272
273
|
if (resource && resource.data) {
|
|
273
274
|
let inverseInternalModel = this.store._internalModelForResource(resource.data);
|
|
@@ -4,6 +4,8 @@ import { cached, tracked } from '@glimmer/tracking';
|
|
|
4
4
|
|
|
5
5
|
import { resolve } from 'rsvp';
|
|
6
6
|
|
|
7
|
+
import { ManyArray } from 'ember-data/-private';
|
|
8
|
+
|
|
7
9
|
import type { ManyRelationship } from '@ember-data/record-data/-private';
|
|
8
10
|
import { assertPolymorphicType } from '@ember-data/store/-debug';
|
|
9
11
|
|
|
@@ -250,7 +252,7 @@ export default class HasManyReference extends Reference {
|
|
|
250
252
|
*/
|
|
251
253
|
async push(
|
|
252
254
|
objectOrPromise: ExistingResourceObject[] | CollectionResourceDocument | { data: SingleResourceDocument[] }
|
|
253
|
-
): Promise<
|
|
255
|
+
): Promise<ManyArray> {
|
|
254
256
|
const payload = await resolve(objectOrPromise);
|
|
255
257
|
let array: Array<ExistingResourceObject | SingleResourceDocument>;
|
|
256
258
|
|
|
@@ -291,7 +293,7 @@ export default class HasManyReference extends Reference {
|
|
|
291
293
|
});
|
|
292
294
|
|
|
293
295
|
// TODO IGOR it seems wrong that we were returning the many array here
|
|
294
|
-
return internalModel.getHasMany(this.key);
|
|
296
|
+
return internalModel.getHasMany(this.key) as Promise<ManyArray> | ManyArray; // this cast is necessary because typescript does not work properly with custom thenables
|
|
295
297
|
}
|
|
296
298
|
|
|
297
299
|
_isLoaded() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getOwner } from '@ember/application';
|
|
2
2
|
import { get } from '@ember/object';
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
import { importSync } from '@embroider/macros';
|
|
5
5
|
|
|
6
6
|
import type Model from '@ember-data/model';
|
|
7
7
|
import { HAS_MODEL_PACKAGE } from '@ember-data/private-build-infra';
|
|
@@ -18,7 +18,7 @@ if (HAS_MODEL_PACKAGE) {
|
|
|
18
18
|
let _found;
|
|
19
19
|
_modelForMixin = function () {
|
|
20
20
|
if (!_found) {
|
|
21
|
-
_found =
|
|
21
|
+
_found = (importSync('@ember-data/model/-private') as typeof import('@ember-data/model/-private'))._modelForMixin;
|
|
22
22
|
}
|
|
23
23
|
return _found(...arguments);
|
|
24
24
|
};
|
|
@@ -3,40 +3,41 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { ModelSchema } from '../ts-interfaces/ds-model';
|
|
6
|
+
import { FindOptions } from '../ts-interfaces/store';
|
|
6
7
|
import type { Dict } from '../ts-interfaces/utils';
|
|
7
8
|
import type RecordArray from './record-arrays/record-array';
|
|
8
9
|
import type Snapshot from './snapshot';
|
|
9
10
|
/**
|
|
10
11
|
SnapshotRecordArray is not directly instantiable.
|
|
11
12
|
Instances are provided to consuming application's
|
|
12
|
-
adapters for certain requests.
|
|
13
|
+
adapters for certain requests.
|
|
13
14
|
|
|
14
15
|
@class SnapshotRecordArray
|
|
15
16
|
@public
|
|
16
17
|
*/
|
|
17
18
|
export default class SnapshotRecordArray {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
declare _snapshots: Snapshot[] | null;
|
|
20
|
+
declare _recordArray: RecordArray;
|
|
21
|
+
declare _type: ModelSchema | null;
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
declare length: number;
|
|
24
|
+
declare meta: Dict<unknown> | null;
|
|
25
|
+
declare adapterOptions?: Dict<unknown>;
|
|
26
|
+
declare include?: string;
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
SnapshotRecordArray is not directly instantiable.
|
|
29
30
|
Instances are provided to consuming application's
|
|
30
|
-
adapters and serializers for certain requests.
|
|
31
|
+
adapters and serializers for certain requests.
|
|
31
32
|
|
|
32
33
|
@method constructor
|
|
33
34
|
@private
|
|
34
35
|
@constructor
|
|
35
36
|
@param {RecordArray} recordArray
|
|
36
37
|
@param {Object} meta
|
|
37
|
-
@param options
|
|
38
|
+
@param options
|
|
38
39
|
*/
|
|
39
|
-
constructor(recordArray: RecordArray, meta
|
|
40
|
+
constructor(recordArray: RecordArray, meta: Dict<unknown> | null, options: FindOptions = {}) {
|
|
40
41
|
/**
|
|
41
42
|
An array of snapshots
|
|
42
43
|
@private
|
|
@@ -4,10 +4,19 @@
|
|
|
4
4
|
import { assert } from '@ember/debug';
|
|
5
5
|
import { get } from '@ember/object';
|
|
6
6
|
|
|
7
|
+
import { importSync } from '@embroider/macros';
|
|
8
|
+
|
|
7
9
|
import { HAS_RECORD_DATA_PACKAGE } from '@ember-data/private-build-infra';
|
|
10
|
+
import type BelongsToRelationship from '@ember-data/record-data/addon/-private/relationships/state/belongs-to';
|
|
11
|
+
import type ManyRelationship from '@ember-data/record-data/addon/-private/relationships/state/has-many';
|
|
12
|
+
import type {
|
|
13
|
+
ExistingResourceIdentifierObject,
|
|
14
|
+
NewResourceIdentifierObject,
|
|
15
|
+
} from '@ember-data/store/-private/ts-interfaces/ember-data-json-api';
|
|
8
16
|
|
|
9
17
|
import type { DSModel, DSModelSchema, ModelSchema } from '../ts-interfaces/ds-model';
|
|
10
18
|
import type { StableRecordIdentifier } from '../ts-interfaces/identifier';
|
|
19
|
+
import { OptionsHash } from '../ts-interfaces/minimum-serializer-interface';
|
|
11
20
|
import type { ChangedAttributesHash } from '../ts-interfaces/record-data';
|
|
12
21
|
import type { AttributeSchema, RelationshipSchema } from '../ts-interfaces/record-data-schemas';
|
|
13
22
|
import type { RecordInstance } from '../ts-interfaces/record-instance';
|
|
@@ -322,9 +331,11 @@ export default class Snapshot implements Snapshot {
|
|
|
322
331
|
assert(`snapshot.belongsTo only supported when using the package @ember-data/record-data`);
|
|
323
332
|
}
|
|
324
333
|
|
|
325
|
-
const graphFor =
|
|
334
|
+
const graphFor = (
|
|
335
|
+
importSync('@ember-data/record-data/-private') as typeof import('@ember-data/record-data/-private')
|
|
336
|
+
).graphFor;
|
|
326
337
|
const { identifier } = this;
|
|
327
|
-
const relationship = graphFor(this._store._storeWrapper).get(identifier, keyName);
|
|
338
|
+
const relationship = graphFor(this._store._storeWrapper).get(identifier, keyName) as BelongsToRelationship;
|
|
328
339
|
|
|
329
340
|
assert(
|
|
330
341
|
`You looked up the ${keyName} belongsTo relationship for { type: ${identifier.type}, id: ${identifier.id}, lid: ${identifier.lid} but no such relationship was found.`,
|
|
@@ -421,9 +432,11 @@ export default class Snapshot implements Snapshot {
|
|
|
421
432
|
assert(`snapshot.hasMany only supported when using the package @ember-data/record-data`);
|
|
422
433
|
}
|
|
423
434
|
|
|
424
|
-
const graphFor =
|
|
435
|
+
const graphFor = (
|
|
436
|
+
importSync('@ember-data/record-data/-private') as typeof import('@ember-data/record-data/-private')
|
|
437
|
+
).graphFor;
|
|
425
438
|
const { identifier } = this;
|
|
426
|
-
const relationship = graphFor(this._store._storeWrapper).get(identifier, keyName);
|
|
439
|
+
const relationship = graphFor(this._store._storeWrapper).get(identifier, keyName) as ManyRelationship;
|
|
427
440
|
assert(
|
|
428
441
|
`You looked up the ${keyName} hasMany relationship for { type: ${identifier.type}, id: ${identifier.id}, lid: ${identifier.lid} but no such relationship was found.`,
|
|
429
442
|
relationship
|
|
@@ -441,7 +454,9 @@ export default class Snapshot implements Snapshot {
|
|
|
441
454
|
let internalModel = store._internalModelForResource(member);
|
|
442
455
|
if (!internalModel.isDeleted()) {
|
|
443
456
|
if (returnModeIsIds) {
|
|
444
|
-
(results as RecordId[]).push(
|
|
457
|
+
(results as RecordId[]).push(
|
|
458
|
+
(member as ExistingResourceIdentifierObject | NewResourceIdentifierObject).id || null
|
|
459
|
+
);
|
|
445
460
|
} else {
|
|
446
461
|
(results as Snapshot[]).push(internalModel.createSnapshot());
|
|
447
462
|
}
|
|
@@ -534,7 +549,9 @@ export default class Snapshot implements Snapshot {
|
|
|
534
549
|
@return {Object} an object whose values are primitive JSON values only
|
|
535
550
|
@public
|
|
536
551
|
*/
|
|
537
|
-
serialize(options
|
|
538
|
-
|
|
552
|
+
serialize(options?: OptionsHash): unknown {
|
|
553
|
+
const serializer = this._store.serializerFor(this.modelName);
|
|
554
|
+
assert(`Cannot serialize record, no serializer found`, serializer);
|
|
555
|
+
return serializer.serialize(this, options);
|
|
539
556
|
}
|
|
540
557
|
}
|