@ember-data/store 4.2.0-beta.0 → 4.3.0
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/identifiers/cache.ts +3 -16
- package/addon/-private/identifiers/is-stable-identifier.ts +2 -2
- package/addon/-private/index.ts +1 -3
- package/addon/-private/system/core-store.ts +192 -958
- package/addon/-private/system/ds-model-store.ts +20 -111
- package/addon/-private/system/fetch-manager.ts +11 -5
- package/addon/-private/system/model/internal-model.ts +92 -345
- package/addon/-private/system/model/shim-model-class.ts +15 -16
- package/addon/-private/system/model/states.js +2 -14
- package/addon/-private/system/record-array-manager.js +21 -70
- package/addon/-private/system/record-arrays/adapter-populated-record-array.js +1 -20
- package/addon/-private/system/record-arrays/record-array.js +1 -8
- package/addon/-private/system/record-data-for.ts +10 -8
- package/addon/-private/system/record-notification-manager.ts +11 -10
- package/addon/-private/system/references/belongs-to.ts +32 -67
- package/addon/-private/system/references/has-many.ts +21 -41
- package/addon/-private/system/references/record.ts +15 -27
- package/addon/-private/system/references/reference.ts +4 -11
- package/addon/-private/system/schema-definition-service.ts +2 -2
- package/addon/-private/system/snapshot.ts +28 -48
- package/addon/-private/system/store/finders.js +2 -96
- package/addon/-private/system/store/internal-model-factory.ts +34 -28
- package/addon/-private/system/store/record-data-store-wrapper.ts +28 -36
- package/addon/-private/system/weak-cache.ts +125 -0
- package/addon/-private/ts-interfaces/fetch-manager.ts +4 -0
- package/addon/-private/ts-interfaces/identifier.ts +2 -2
- package/addon/-private/ts-interfaces/minimum-adapter-interface.ts +0 -1
- package/addon/-private/ts-interfaces/schema-definition-service.ts +2 -2
- package/package.json +16 -16
- package/addon/-private/system/deprecated-evented.js +0 -92
|
@@ -4,7 +4,6 @@ import { cached, tracked } from '@glimmer/tracking';
|
|
|
4
4
|
|
|
5
5
|
import { resolve } from 'rsvp';
|
|
6
6
|
|
|
7
|
-
import { CUSTOM_MODEL_CLASS } from '@ember-data/canary-features';
|
|
8
7
|
import type { ManyRelationship } from '@ember-data/record-data/-private';
|
|
9
8
|
import { assertPolymorphicType } from '@ember-data/store/-debug';
|
|
10
9
|
|
|
@@ -18,8 +17,7 @@ import CoreStore from '../core-store';
|
|
|
18
17
|
import { NotificationType, unsubscribe } from '../record-notification-manager';
|
|
19
18
|
import { internalModelFactoryFor, recordIdentifierFor } from '../store/internal-model-factory';
|
|
20
19
|
import RecordReference from './record';
|
|
21
|
-
import Reference
|
|
22
|
-
|
|
20
|
+
import Reference from './reference';
|
|
23
21
|
/**
|
|
24
22
|
@module @ember-data/store
|
|
25
23
|
*/
|
|
@@ -37,10 +35,10 @@ export default class HasManyReference extends Reference {
|
|
|
37
35
|
declare hasManyRelationship: ManyRelationship;
|
|
38
36
|
declare type: string;
|
|
39
37
|
declare parent: RecordReference;
|
|
40
|
-
declare parentIdentifier: StableRecordIdentifier;
|
|
41
38
|
|
|
42
39
|
// unsubscribe tokens given to us by the notification manager
|
|
43
40
|
#token!: Object;
|
|
41
|
+
#identifier: StableRecordIdentifier;
|
|
44
42
|
#relatedTokenMap!: Map<StableRecordIdentifier, Object>;
|
|
45
43
|
|
|
46
44
|
@tracked _ref = 0;
|
|
@@ -57,29 +55,25 @@ export default class HasManyReference extends Reference {
|
|
|
57
55
|
this.type = hasManyRelationship.definition.type;
|
|
58
56
|
|
|
59
57
|
this.parent = internalModelFactoryFor(store).peek(parentIdentifier)!.recordReference;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
(
|
|
65
|
-
|
|
66
|
-
this._ref++;
|
|
67
|
-
}
|
|
58
|
+
this.#identifier = parentIdentifier;
|
|
59
|
+
this.#token = store._notificationManager.subscribe(
|
|
60
|
+
parentIdentifier,
|
|
61
|
+
(_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
|
|
62
|
+
if ((bucket === 'relationships' || bucket === 'property') && notifiedKey === key) {
|
|
63
|
+
this._ref++;
|
|
68
64
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
this.#relatedTokenMap = new Map();
|
|
72
68
|
// TODO inverse
|
|
73
69
|
}
|
|
74
70
|
|
|
75
71
|
destroy() {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
this.#relatedTokenMap.clear();
|
|
82
|
-
}
|
|
72
|
+
unsubscribe(this.#token);
|
|
73
|
+
this.#relatedTokenMap.forEach((token) => {
|
|
74
|
+
unsubscribe(token);
|
|
75
|
+
});
|
|
76
|
+
this.#relatedTokenMap.clear();
|
|
83
77
|
}
|
|
84
78
|
|
|
85
79
|
@cached
|
|
@@ -206,21 +200,7 @@ export default class HasManyReference extends Reference {
|
|
|
206
200
|
@return {Array} The ids in this has-many relationship
|
|
207
201
|
*/
|
|
208
202
|
ids(): Array<string | null> {
|
|
209
|
-
|
|
210
|
-
return this._relatedIdentifiers.map((identifier) => identifier.id);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
let resource = this._resource();
|
|
214
|
-
|
|
215
|
-
if (resource && resource.data) {
|
|
216
|
-
return resource.data.map((resourceIdentifier) => {
|
|
217
|
-
const identifier = this.store.identifierCache.getOrCreateRecordIdentifier(resourceIdentifier);
|
|
218
|
-
|
|
219
|
-
return identifier.id;
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
return [];
|
|
203
|
+
return this._relatedIdentifiers.map((identifier) => identifier.id);
|
|
224
204
|
}
|
|
225
205
|
|
|
226
206
|
/**
|
|
@@ -280,7 +260,7 @@ export default class HasManyReference extends Reference {
|
|
|
280
260
|
array = payload as ExistingResourceObject[];
|
|
281
261
|
}
|
|
282
262
|
|
|
283
|
-
const internalModel =
|
|
263
|
+
const internalModel = internalModelFactoryFor(this.store).peek(this.#identifier)!;
|
|
284
264
|
const { store } = this;
|
|
285
265
|
|
|
286
266
|
let identifiers = array.map((obj) => {
|
|
@@ -371,7 +351,7 @@ export default class HasManyReference extends Reference {
|
|
|
371
351
|
@return {ManyArray}
|
|
372
352
|
*/
|
|
373
353
|
value() {
|
|
374
|
-
|
|
354
|
+
const internalModel = internalModelFactoryFor(this.store).peek(this.#identifier)!;
|
|
375
355
|
if (this._isLoaded()) {
|
|
376
356
|
return internalModel.getManyArray(this.key);
|
|
377
357
|
}
|
|
@@ -444,7 +424,7 @@ export default class HasManyReference extends Reference {
|
|
|
444
424
|
this has-many relationship.
|
|
445
425
|
*/
|
|
446
426
|
load(options) {
|
|
447
|
-
|
|
427
|
+
const internalModel = internalModelFactoryFor(this.store).peek(this.#identifier)!;
|
|
448
428
|
return internalModel.getHasMany(this.key, options);
|
|
449
429
|
}
|
|
450
430
|
|
|
@@ -499,7 +479,7 @@ export default class HasManyReference extends Reference {
|
|
|
499
479
|
@return {Promise} a promise that resolves with the ManyArray in this has-many relationship.
|
|
500
480
|
*/
|
|
501
481
|
reload(options) {
|
|
502
|
-
|
|
482
|
+
const internalModel = internalModelFactoryFor(this.store).peek(this.#identifier)!;
|
|
503
483
|
return internalModel.reloadHasMany(this.key, options);
|
|
504
484
|
}
|
|
505
485
|
}
|
|
@@ -3,15 +3,13 @@ import { cached, tracked } from '@glimmer/tracking';
|
|
|
3
3
|
|
|
4
4
|
import RSVP, { resolve } from 'rsvp';
|
|
5
5
|
|
|
6
|
-
import { CUSTOM_MODEL_CLASS } from '@ember-data/canary-features';
|
|
7
|
-
|
|
8
6
|
import type { SingleResourceDocument } from '../../ts-interfaces/ember-data-json-api';
|
|
9
7
|
import type { StableRecordIdentifier } from '../../ts-interfaces/identifier';
|
|
10
8
|
import type { RecordInstance } from '../../ts-interfaces/record-instance';
|
|
11
9
|
import type CoreStore from '../core-store';
|
|
12
10
|
import { NotificationType, unsubscribe } from '../record-notification-manager';
|
|
13
|
-
import
|
|
14
|
-
|
|
11
|
+
import { internalModelFactoryFor } from '../store/internal-model-factory';
|
|
12
|
+
import Reference from './reference';
|
|
15
13
|
/**
|
|
16
14
|
@module @ember-data/store
|
|
17
15
|
*/
|
|
@@ -27,27 +25,25 @@ import Reference, { internalModelForReference, REFERENCE_CACHE } from './referen
|
|
|
27
25
|
export default class RecordReference extends Reference {
|
|
28
26
|
// unsubscribe token given to us by the notification manager
|
|
29
27
|
#token!: Object;
|
|
28
|
+
#identifier;
|
|
30
29
|
|
|
31
30
|
@tracked _ref = 0;
|
|
32
31
|
|
|
33
32
|
constructor(public store: CoreStore, identifier: StableRecordIdentifier) {
|
|
34
33
|
super(store, identifier);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
34
|
+
this.#identifier = identifier;
|
|
35
|
+
this.#token = store._notificationManager.subscribe(
|
|
36
|
+
identifier,
|
|
37
|
+
(_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
|
|
38
|
+
if (bucket === 'identity' || ((bucket === 'attributes' || bucket === 'property') && notifiedKey === 'id')) {
|
|
39
|
+
this._ref++;
|
|
42
40
|
}
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
}
|
|
42
|
+
);
|
|
45
43
|
}
|
|
46
44
|
|
|
47
45
|
destroy() {
|
|
48
|
-
|
|
49
|
-
unsubscribe(this.#token);
|
|
50
|
-
}
|
|
46
|
+
unsubscribe(this.#token);
|
|
51
47
|
}
|
|
52
48
|
|
|
53
49
|
public get type(): string {
|
|
@@ -85,15 +81,7 @@ export default class RecordReference extends Reference {
|
|
|
85
81
|
@return {String} The id of the record.
|
|
86
82
|
*/
|
|
87
83
|
id() {
|
|
88
|
-
|
|
89
|
-
return this._id;
|
|
90
|
-
}
|
|
91
|
-
let identifier = this.identifier();
|
|
92
|
-
if (identifier) {
|
|
93
|
-
return identifier.id;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return null;
|
|
84
|
+
return this._id;
|
|
97
85
|
}
|
|
98
86
|
|
|
99
87
|
/**
|
|
@@ -115,7 +103,7 @@ export default class RecordReference extends Reference {
|
|
|
115
103
|
@return {String} The identifier of the record.
|
|
116
104
|
*/
|
|
117
105
|
identifier(): StableRecordIdentifier {
|
|
118
|
-
return
|
|
106
|
+
return this.#identifier;
|
|
119
107
|
}
|
|
120
108
|
|
|
121
109
|
/**
|
|
@@ -203,7 +191,7 @@ export default class RecordReference extends Reference {
|
|
|
203
191
|
*/
|
|
204
192
|
value(): RecordInstance | null {
|
|
205
193
|
if (this.id() !== null) {
|
|
206
|
-
let internalModel =
|
|
194
|
+
let internalModel = internalModelFactoryFor(this.store).peek(this.#identifier);
|
|
207
195
|
if (internalModel && internalModel.currentState.isLoaded) {
|
|
208
196
|
return internalModel.getRecord();
|
|
209
197
|
}
|
|
@@ -5,9 +5,6 @@ import type { StableRecordIdentifier } from '../../ts-interfaces/identifier';
|
|
|
5
5
|
import type { JsonApiRelationship } from '../../ts-interfaces/record-data-json-api';
|
|
6
6
|
import type { Dict } from '../../ts-interfaces/utils';
|
|
7
7
|
import type CoreStore from '../core-store';
|
|
8
|
-
import type InternalModel from '../model/internal-model';
|
|
9
|
-
import { internalModelFactoryFor } from '../store/internal-model-factory';
|
|
10
|
-
|
|
11
8
|
/**
|
|
12
9
|
@module @ember-data/store
|
|
13
10
|
*/
|
|
@@ -25,12 +22,6 @@ function isResourceIdentiferWithRelatedLinks(
|
|
|
25
22
|
return value && value.links && value.links.related;
|
|
26
23
|
}
|
|
27
24
|
|
|
28
|
-
export const REFERENCE_CACHE = new WeakMap<Reference, StableRecordIdentifier>();
|
|
29
|
-
|
|
30
|
-
export function internalModelForReference(reference: Reference): InternalModel | null | undefined {
|
|
31
|
-
return internalModelFactoryFor(reference.store).peek(REFERENCE_CACHE.get(reference) as StableRecordIdentifier);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
25
|
/**
|
|
35
26
|
This is the baseClass for the different References
|
|
36
27
|
like RecordReference/HasManyReference/BelongsToReference
|
|
@@ -42,12 +33,14 @@ interface Reference {
|
|
|
42
33
|
links(): PaginationLinks | null;
|
|
43
34
|
}
|
|
44
35
|
abstract class Reference {
|
|
36
|
+
#identifier: StableRecordIdentifier;
|
|
37
|
+
|
|
45
38
|
constructor(public store: CoreStore, identifier: StableRecordIdentifier) {
|
|
46
|
-
|
|
39
|
+
this.#identifier = identifier;
|
|
47
40
|
}
|
|
48
41
|
|
|
49
42
|
get recordData() {
|
|
50
|
-
return this.store.recordDataFor(
|
|
43
|
+
return this.store.recordDataFor(this.#identifier, false);
|
|
51
44
|
}
|
|
52
45
|
|
|
53
46
|
public _resource(): ResourceIdentifier | JsonApiRelationship | void {}
|
|
@@ -32,7 +32,7 @@ export class DSModelSchemaDefinitionService {
|
|
|
32
32
|
constructor(public store: Store) {}
|
|
33
33
|
|
|
34
34
|
// Following the existing RD implementation
|
|
35
|
-
attributesDefinitionFor(identifier: RecordIdentifier | string): AttributesSchema {
|
|
35
|
+
attributesDefinitionFor(identifier: RecordIdentifier | { type: string }): AttributesSchema {
|
|
36
36
|
let modelName, attributes;
|
|
37
37
|
if (typeof identifier === 'string') {
|
|
38
38
|
modelName = identifier;
|
|
@@ -55,7 +55,7 @@ export class DSModelSchemaDefinitionService {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
// Following the existing RD implementation
|
|
58
|
-
relationshipsDefinitionFor(identifier: RecordIdentifier | string): RelationshipsSchema {
|
|
58
|
+
relationshipsDefinitionFor(identifier: RecordIdentifier | { type: string }): RelationshipsSchema {
|
|
59
59
|
let modelName, relationships;
|
|
60
60
|
if (typeof identifier === 'string') {
|
|
61
61
|
modelName = identifier;
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
import { assert } from '@ember/debug';
|
|
5
5
|
import { get } from '@ember/object';
|
|
6
6
|
|
|
7
|
-
import { CUSTOM_MODEL_CLASS } from '@ember-data/canary-features';
|
|
8
7
|
import { HAS_RECORD_DATA_PACKAGE } from '@ember-data/private-build-infra';
|
|
9
8
|
|
|
10
9
|
import type { DSModel, DSModelSchema, ModelSchema } from '../ts-interfaces/ds-model';
|
|
@@ -65,10 +64,15 @@ export default class Snapshot implements Snapshot {
|
|
|
65
64
|
let internalModel = (this._internalModel = _store._internalModelForResource(identifier));
|
|
66
65
|
this.modelName = identifier.type;
|
|
67
66
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
/**
|
|
68
|
+
The unique RecordIdentifier associated with this Snapshot.
|
|
69
|
+
|
|
70
|
+
@property identifier
|
|
71
|
+
@public
|
|
72
|
+
@type {StableRecordIdentifier}
|
|
73
|
+
*/
|
|
74
|
+
this.identifier = identifier;
|
|
75
|
+
|
|
72
76
|
/*
|
|
73
77
|
If the internalModel does not yet have a record, then we are
|
|
74
78
|
likely a snapshot being provided to a find request, so we
|
|
@@ -151,26 +155,15 @@ export default class Snapshot implements Snapshot {
|
|
|
151
155
|
}
|
|
152
156
|
let record = this.record;
|
|
153
157
|
let attributes = (this.__attributes = Object.create(null));
|
|
154
|
-
let attrs
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if (schemaIsDSModel(this.type)) {
|
|
164
|
-
// if the schema is for a DSModel then the instance is too
|
|
165
|
-
attributes[keyName] = get(record as DSModel, keyName);
|
|
166
|
-
} else {
|
|
167
|
-
attributes[keyName] = recordDataFor(this._internalModel).getAttr(keyName);
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
} else {
|
|
171
|
-
// When CUSTOM_MODEL_CLASS is false `record` must be DSModel
|
|
172
|
-
(record as DSModel).eachAttribute((keyName) => (attributes[keyName] = get(record as DSModel, keyName)));
|
|
173
|
-
}
|
|
158
|
+
let attrs = Object.keys(this._store._attributesDefinitionFor(this.identifier));
|
|
159
|
+
attrs.forEach((keyName) => {
|
|
160
|
+
if (schemaIsDSModel(this.type)) {
|
|
161
|
+
// if the schema is for a DSModel then the instance is too
|
|
162
|
+
attributes[keyName] = get(record as DSModel, keyName);
|
|
163
|
+
} else {
|
|
164
|
+
attributes[keyName] = recordDataFor(this._internalModel).getAttr(keyName);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
174
167
|
|
|
175
168
|
return attributes;
|
|
176
169
|
}
|
|
@@ -187,9 +180,6 @@ export default class Snapshot implements Snapshot {
|
|
|
187
180
|
}
|
|
188
181
|
|
|
189
182
|
get isNew(): boolean {
|
|
190
|
-
if (!CUSTOM_MODEL_CLASS) {
|
|
191
|
-
throw new Error('isNew is only available when custom model class ff is on');
|
|
192
|
-
}
|
|
193
183
|
return this._internalModel.isNew();
|
|
194
184
|
}
|
|
195
185
|
|
|
@@ -333,7 +323,7 @@ export default class Snapshot implements Snapshot {
|
|
|
333
323
|
}
|
|
334
324
|
|
|
335
325
|
const graphFor = require('@ember-data/record-data/-private').graphFor;
|
|
336
|
-
const { identifier } =
|
|
326
|
+
const { identifier } = this;
|
|
337
327
|
const relationship = graphFor(this._store._storeWrapper).get(identifier, keyName);
|
|
338
328
|
|
|
339
329
|
assert(
|
|
@@ -432,7 +422,7 @@ export default class Snapshot implements Snapshot {
|
|
|
432
422
|
}
|
|
433
423
|
|
|
434
424
|
const graphFor = require('@ember-data/record-data/-private').graphFor;
|
|
435
|
-
const { identifier } =
|
|
425
|
+
const { identifier } = this;
|
|
436
426
|
const relationship = graphFor(this._store._storeWrapper).get(identifier, keyName);
|
|
437
427
|
assert(
|
|
438
428
|
`You looked up the ${keyName} hasMany relationship for { type: ${identifier.type}, id: ${identifier.id}, lid: ${identifier.lid} but no such relationship was found.`,
|
|
@@ -488,15 +478,10 @@ export default class Snapshot implements Snapshot {
|
|
|
488
478
|
@public
|
|
489
479
|
*/
|
|
490
480
|
eachAttribute(callback: (key: string, meta: AttributeSchema) => void, binding?: unknown): void {
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
});
|
|
496
|
-
} else {
|
|
497
|
-
// in the non CUSTOM_MODEL_CLASS world we only have DSModel instances
|
|
498
|
-
(this.record as DSModel).eachAttribute(callback, binding);
|
|
499
|
-
}
|
|
481
|
+
let attrDefs = this._store._attributesDefinitionFor(this.identifier);
|
|
482
|
+
Object.keys(attrDefs).forEach((key) => {
|
|
483
|
+
callback.call(binding, key, attrDefs[key] as AttributeSchema);
|
|
484
|
+
});
|
|
500
485
|
}
|
|
501
486
|
|
|
502
487
|
/**
|
|
@@ -517,15 +502,10 @@ export default class Snapshot implements Snapshot {
|
|
|
517
502
|
@public
|
|
518
503
|
*/
|
|
519
504
|
eachRelationship(callback: (key: string, meta: RelationshipSchema) => void, binding?: unknown): void {
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
});
|
|
525
|
-
} else {
|
|
526
|
-
// in the non CUSTOM_MODEL_CLASS world we only have DSModel instances
|
|
527
|
-
(this.record as DSModel).eachRelationship(callback, binding);
|
|
528
|
-
}
|
|
505
|
+
let relationshipDefs = this._store._relationshipsDefinitionFor(this.identifier);
|
|
506
|
+
Object.keys(relationshipDefs).forEach((key) => {
|
|
507
|
+
callback.call(binding, key, relationshipDefs[key] as RelationshipSchema);
|
|
508
|
+
});
|
|
529
509
|
}
|
|
530
510
|
|
|
531
511
|
/**
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import { assert
|
|
1
|
+
import { assert } from '@ember/debug';
|
|
2
2
|
import { DEBUG } from '@glimmer/env';
|
|
3
3
|
|
|
4
4
|
import { Promise } from 'rsvp';
|
|
5
5
|
|
|
6
|
-
import { REQUEST_SERVICE } from '@ember-data/canary-features';
|
|
7
|
-
|
|
8
|
-
import coerceId from '../coerce-id';
|
|
9
6
|
import { _bind, _guard, _objectIsAlive, guardDestroyedStore } from './common';
|
|
10
7
|
import { normalizeResponseHelper } from './serializer-response';
|
|
11
8
|
|
|
@@ -21,88 +18,6 @@ function payloadIsNotBlank(adapterPayload) {
|
|
|
21
18
|
}
|
|
22
19
|
}
|
|
23
20
|
|
|
24
|
-
export function _find(adapter, store, modelClass, id, internalModel, options) {
|
|
25
|
-
if (REQUEST_SERVICE) {
|
|
26
|
-
assert(`Requests made when REQUEST_SERVICE=true should not use the legacy finders`);
|
|
27
|
-
}
|
|
28
|
-
let snapshot = internalModel.createSnapshot(options);
|
|
29
|
-
let { modelName } = internalModel;
|
|
30
|
-
let promise = Promise.resolve().then(() => {
|
|
31
|
-
return adapter.findRecord(store, modelClass, id, snapshot);
|
|
32
|
-
});
|
|
33
|
-
let label = `DS: Handle Adapter#findRecord of '${modelName}' with id: '${id}'`;
|
|
34
|
-
const { identifier } = internalModel;
|
|
35
|
-
|
|
36
|
-
promise = guardDestroyedStore(promise, store, label);
|
|
37
|
-
|
|
38
|
-
return promise.then(
|
|
39
|
-
(adapterPayload) => {
|
|
40
|
-
assert(
|
|
41
|
-
`You made a 'findRecord' request for a '${modelName}' with id '${id}', but the adapter's response did not have any data`,
|
|
42
|
-
payloadIsNotBlank(adapterPayload)
|
|
43
|
-
);
|
|
44
|
-
let serializer = store.serializerFor(modelName);
|
|
45
|
-
let payload = normalizeResponseHelper(serializer, store, modelClass, adapterPayload, id, 'findRecord');
|
|
46
|
-
assert(
|
|
47
|
-
`Ember Data expected the primary data returned from a 'findRecord' response to be an object but instead it found an array.`,
|
|
48
|
-
!Array.isArray(payload.data)
|
|
49
|
-
);
|
|
50
|
-
assert(
|
|
51
|
-
`The 'findRecord' request for ${modelName}:${id} resolved indicating success but contained no primary data. To indicate a 404 not found you should either reject the promise returned by the adapter's findRecord method or throw a NotFoundError.`,
|
|
52
|
-
'data' in payload && payload.data !== null && typeof payload.data === 'object'
|
|
53
|
-
);
|
|
54
|
-
warn(
|
|
55
|
-
`You requested a record of type '${modelName}' with id '${id}' but the adapter returned a payload with primary data having an id of '${payload.data.id}'. Use 'store.findRecord()' when the requested id is the same as the one returned by the adapter. In other cases use 'store.queryRecord()' instead.`,
|
|
56
|
-
coerceId(payload.data.id) === coerceId(id),
|
|
57
|
-
{
|
|
58
|
-
id: 'ds.store.findRecord.id-mismatch',
|
|
59
|
-
}
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
// ensure that regardless of id returned we assign to the correct record
|
|
63
|
-
payload.data.lid = identifier.lid;
|
|
64
|
-
|
|
65
|
-
return store._push(payload);
|
|
66
|
-
},
|
|
67
|
-
(error) => {
|
|
68
|
-
internalModel.send('notFound');
|
|
69
|
-
if (internalModel.currentState.isEmpty) {
|
|
70
|
-
internalModel.unloadRecord();
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
throw error;
|
|
74
|
-
},
|
|
75
|
-
`DS: Extract payload of '${modelName}'`
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export function _findMany(adapter, store, modelName, ids, internalModels, optionsMap) {
|
|
80
|
-
let snapshots = internalModels.map((internalModel) => internalModel.createSnapshot(optionsMap.get(internalModel)));
|
|
81
|
-
let modelClass = store.modelFor(modelName); // `adapter.findMany` gets the modelClass still
|
|
82
|
-
let promise = adapter.findMany(store, modelClass, ids, snapshots);
|
|
83
|
-
let label = `DS: Handle Adapter#findMany of '${modelName}'`;
|
|
84
|
-
|
|
85
|
-
if (promise === undefined) {
|
|
86
|
-
throw new Error('adapter.findMany returned undefined, this was very likely a mistake');
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
promise = guardDestroyedStore(promise, store, label);
|
|
90
|
-
|
|
91
|
-
return promise.then(
|
|
92
|
-
(adapterPayload) => {
|
|
93
|
-
assert(
|
|
94
|
-
`You made a 'findMany' request for '${modelName}' records with ids '[${ids}]', but the adapter's response did not have any data`,
|
|
95
|
-
payloadIsNotBlank(adapterPayload)
|
|
96
|
-
);
|
|
97
|
-
let serializer = store.serializerFor(modelName);
|
|
98
|
-
let payload = normalizeResponseHelper(serializer, store, modelClass, adapterPayload, null, 'findMany');
|
|
99
|
-
return store._push(payload);
|
|
100
|
-
},
|
|
101
|
-
null,
|
|
102
|
-
`DS: Extract payload of ${modelName}`
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
21
|
function iterateData(data, fn) {
|
|
107
22
|
if (Array.isArray(data)) {
|
|
108
23
|
return data.map(fn);
|
|
@@ -201,16 +116,7 @@ function ensureRelationshipIsSetToParent(payload, parentInternalModel, store, pa
|
|
|
201
116
|
`Please update the response from the server or change your serializer to either ensure that the response for only includes ${quotedType} records that specify ${expectedModel} as their ${quotedInverse}, or omit the ${quotedInverse} relationship from the response.`,
|
|
202
117
|
].join('\n');
|
|
203
118
|
|
|
204
|
-
|
|
205
|
-
deprecate(message + '\n', false, {
|
|
206
|
-
id: 'mismatched-inverse-relationship-data-from-payload',
|
|
207
|
-
until: '3.8',
|
|
208
|
-
for: '@ember-data/store',
|
|
209
|
-
since: {
|
|
210
|
-
available: '3.8',
|
|
211
|
-
enabled: '3.8',
|
|
212
|
-
},
|
|
213
|
-
});
|
|
119
|
+
assert(message);
|
|
214
120
|
}
|
|
215
121
|
|
|
216
122
|
if (kind !== 'hasMany' || typeof relationshipData !== 'undefined') {
|
|
@@ -3,7 +3,6 @@ import { isNone } from '@ember/utils';
|
|
|
3
3
|
import { DEBUG } from '@glimmer/env';
|
|
4
4
|
|
|
5
5
|
import type { IdentifierCache } from '../../identifiers/cache';
|
|
6
|
-
import { identifierCacheFor } from '../../identifiers/cache';
|
|
7
6
|
import type {
|
|
8
7
|
ExistingResourceObject,
|
|
9
8
|
NewResourceIdentifierObject,
|
|
@@ -16,39 +15,53 @@ import type CoreStore from '../core-store';
|
|
|
16
15
|
import IdentityMap from '../identity-map';
|
|
17
16
|
import type InternalModelMap from '../internal-model-map';
|
|
18
17
|
import InternalModel from '../model/internal-model';
|
|
18
|
+
import WeakCache from '../weak-cache';
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
@module @ember-data/store
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
const FactoryCache = new
|
|
24
|
+
const FactoryCache = new WeakCache<CoreStore, InternalModelFactory>(DEBUG ? 'internal-model-factory' : '');
|
|
25
|
+
FactoryCache._generator = (store: CoreStore) => {
|
|
26
|
+
return new InternalModelFactory(store);
|
|
27
|
+
};
|
|
25
28
|
type NewResourceInfo = { type: string; id: string | null };
|
|
26
29
|
|
|
27
|
-
const RecordCache = new
|
|
30
|
+
const RecordCache = new WeakCache<RecordInstance, StableRecordIdentifier>(DEBUG ? 'identifier' : '');
|
|
31
|
+
if (DEBUG) {
|
|
32
|
+
RecordCache._expectMsg = (key: RecordInstance) => `${key} is not a record instantiated by @ember-data/store`;
|
|
33
|
+
}
|
|
28
34
|
|
|
29
35
|
export function peekRecordIdentifier(record: any): StableRecordIdentifier | undefined {
|
|
30
36
|
return RecordCache.get(record);
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
/**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
*
|
|
37
|
-
* @method recordIdentifierFor
|
|
38
|
-
* @public
|
|
39
|
-
* @static
|
|
40
|
-
* @for @ember-data/store
|
|
41
|
-
* @param {Object} record a record instance previously obstained from the store.
|
|
42
|
-
* @returns
|
|
43
|
-
*/
|
|
44
|
-
export function recordIdentifierFor(record: RecordInstance): StableRecordIdentifier {
|
|
45
|
-
let identifier = RecordCache.get(record);
|
|
40
|
+
Retrieves the unique referentially-stable [RecordIdentifier](/ember-data/release/classes/StableRecordIdentifier)
|
|
41
|
+
assigned to the given record instance.
|
|
46
42
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
```js
|
|
44
|
+
import { recordIdentifierFor } from "@ember-data/store";
|
|
45
|
+
|
|
46
|
+
// ... gain access to a record, for instance with peekRecord or findRecord
|
|
47
|
+
const record = store.peekRecord("user", "1");
|
|
48
|
+
|
|
49
|
+
// get the identifier for the record (see docs for StableRecordIdentifier)
|
|
50
|
+
const identifier = recordIdentifierFor(record);
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
// access the identifier's properties.
|
|
53
|
+
const { id, type, lid } = identifier;
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
@method recordIdentifierFor
|
|
57
|
+
@public
|
|
58
|
+
@static
|
|
59
|
+
@for @ember-data/store
|
|
60
|
+
@param {Object} record a record instance previously obstained from the store.
|
|
61
|
+
@returns {StableRecordIdentifier}
|
|
62
|
+
*/
|
|
63
|
+
export function recordIdentifierFor(record: RecordInstance): StableRecordIdentifier {
|
|
64
|
+
return RecordCache.getWithError(record);
|
|
52
65
|
}
|
|
53
66
|
|
|
54
67
|
export function setRecordIdentifier(record: RecordInstance, identifier: StableRecordIdentifier): void {
|
|
@@ -68,14 +81,7 @@ export function setRecordIdentifier(record: RecordInstance, identifier: StableRe
|
|
|
68
81
|
}
|
|
69
82
|
|
|
70
83
|
export function internalModelFactoryFor(store: CoreStore): InternalModelFactory {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (factory === undefined) {
|
|
74
|
-
factory = new InternalModelFactory(store);
|
|
75
|
-
FactoryCache.set(store, factory);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return factory;
|
|
84
|
+
return FactoryCache.lookup(store);
|
|
79
85
|
}
|
|
80
86
|
|
|
81
87
|
/**
|
|
@@ -93,7 +99,7 @@ export default class InternalModelFactory {
|
|
|
93
99
|
|
|
94
100
|
constructor(store: CoreStore) {
|
|
95
101
|
this.store = store;
|
|
96
|
-
this.identifierCache =
|
|
102
|
+
this.identifierCache = store.identifierCache;
|
|
97
103
|
this.identifierCache.__configureMerge((identifier, matchedIdentifier, resourceData) => {
|
|
98
104
|
let intendedIdentifier = identifier;
|
|
99
105
|
if (identifier.id !== matchedIdentifier.id) {
|