@ember-data/legacy-compat 4.12.7 → 4.13.0-alpha.1
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/README.md +8 -0
- package/addon-main.cjs +5 -0
- package/{addon/fetch-manager-025964e9.js → dist/-private-BJlhRRce.js} +321 -194
- package/dist/-private-BJlhRRce.js.map +1 -0
- package/dist/-private.js +1 -0
- package/dist/builders.js +303 -0
- package/dist/builders.js.map +1 -0
- package/dist/index.js +1087 -0
- package/dist/index.js.map +1 -0
- package/dist/utils-XGHLsgBS.js +23 -0
- package/dist/utils-XGHLsgBS.js.map +1 -0
- package/dist/utils.js +246 -0
- package/dist/utils.js.map +1 -0
- package/package.json +72 -35
- package/unstable-preview-types/-private.d.ts +17 -0
- package/unstable-preview-types/-private.d.ts.map +1 -0
- package/unstable-preview-types/builders/find-all.d.ts +41 -0
- package/unstable-preview-types/builders/find-all.d.ts.map +1 -0
- package/unstable-preview-types/builders/find-record.d.ts +62 -0
- package/unstable-preview-types/builders/find-record.d.ts.map +1 -0
- package/unstable-preview-types/builders/query.d.ts +72 -0
- package/unstable-preview-types/builders/query.d.ts.map +1 -0
- package/unstable-preview-types/builders/save-record.d.ts +40 -0
- package/unstable-preview-types/builders/save-record.d.ts.map +1 -0
- package/unstable-preview-types/builders/utils.d.ts +6 -0
- package/unstable-preview-types/builders/utils.d.ts.map +1 -0
- package/unstable-preview-types/builders.d.ts +18 -0
- package/unstable-preview-types/builders.d.ts.map +1 -0
- package/unstable-preview-types/index.d.ts +163 -0
- package/unstable-preview-types/index.d.ts.map +1 -0
- package/unstable-preview-types/legacy-network-handler/fetch-manager.d.ts +49 -0
- package/unstable-preview-types/legacy-network-handler/fetch-manager.d.ts.map +1 -0
- package/unstable-preview-types/legacy-network-handler/identifier-has-id.d.ts +5 -0
- package/unstable-preview-types/legacy-network-handler/identifier-has-id.d.ts.map +1 -0
- package/unstable-preview-types/legacy-network-handler/legacy-data-fetch.d.ts +15 -0
- package/unstable-preview-types/legacy-network-handler/legacy-data-fetch.d.ts.map +1 -0
- package/unstable-preview-types/legacy-network-handler/legacy-data-utils.d.ts +8 -0
- package/unstable-preview-types/legacy-network-handler/legacy-data-utils.d.ts.map +1 -0
- package/unstable-preview-types/legacy-network-handler/legacy-network-handler.d.ts +5 -0
- package/unstable-preview-types/legacy-network-handler/legacy-network-handler.d.ts.map +1 -0
- package/unstable-preview-types/legacy-network-handler/minimum-adapter-interface.d.ts +549 -0
- package/unstable-preview-types/legacy-network-handler/minimum-adapter-interface.d.ts.map +1 -0
- package/unstable-preview-types/legacy-network-handler/minimum-serializer-interface.d.ts +235 -0
- package/unstable-preview-types/legacy-network-handler/minimum-serializer-interface.d.ts.map +1 -0
- package/unstable-preview-types/legacy-network-handler/serializer-response.d.ts +9 -0
- package/unstable-preview-types/legacy-network-handler/serializer-response.d.ts.map +1 -0
- package/unstable-preview-types/legacy-network-handler/snapshot-record-array.d.ts +96 -0
- package/unstable-preview-types/legacy-network-handler/snapshot-record-array.d.ts.map +1 -0
- package/unstable-preview-types/legacy-network-handler/snapshot.d.ts +257 -0
- package/unstable-preview-types/legacy-network-handler/snapshot.d.ts.map +1 -0
- package/unstable-preview-types/legacy-network-handler/utils.d.ts +8 -0
- package/unstable-preview-types/legacy-network-handler/utils.d.ts.map +1 -0
- package/unstable-preview-types/utils.d.ts +161 -0
- package/unstable-preview-types/utils.d.ts.map +1 -0
- package/addon/-private.js +0 -1
- package/addon/fetch-manager-025964e9.js.map +0 -1
- package/addon/index.js +0 -673
- package/addon/index.js.map +0 -1
- package/addon-main.js +0 -93
- /package/{addon → dist}/-private.js.map +0 -0
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { deprecate, assert, warn } from '@ember/debug';
|
|
1
|
+
import { deprecate, warn } from '@ember/debug';
|
|
3
2
|
import { SOURCE, coerceId } from '@ember-data/store/-private';
|
|
3
|
+
import { macroCondition, getGlobalConfig, dependencySatisfies, importSync } from '@embroider/macros';
|
|
4
4
|
import { createDeferred } from '@ember-data/request';
|
|
5
|
+
import { getOrSetGlobal } from '@warp-drive/core-types/-private';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
@module @ember-data/legacy-compat
|
|
9
|
+
*/
|
|
10
|
+
|
|
5
11
|
/**
|
|
6
12
|
SnapshotRecordArray is not directly instantiable.
|
|
7
13
|
Instances are provided to consuming application's
|
|
8
|
-
adapters for certain requests.
|
|
14
|
+
adapters for certain `findAll` requests.
|
|
9
15
|
|
|
10
16
|
@class SnapshotRecordArray
|
|
11
17
|
@public
|
|
@@ -135,6 +141,7 @@ class SnapshotRecordArray {
|
|
|
135
141
|
if (this._snapshots !== null) {
|
|
136
142
|
return this._snapshots;
|
|
137
143
|
}
|
|
144
|
+
upgradeStore(this.__store);
|
|
138
145
|
const {
|
|
139
146
|
_fetchManager
|
|
140
147
|
} = this.__store;
|
|
@@ -142,7 +149,7 @@ class SnapshotRecordArray {
|
|
|
142
149
|
return this._snapshots;
|
|
143
150
|
}
|
|
144
151
|
}
|
|
145
|
-
if (macroCondition(
|
|
152
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_SNAPSHOT_MODEL_CLASS_ACCESS)) {
|
|
146
153
|
/**
|
|
147
154
|
The type of the underlying records for the snapshots in the array, as a Model
|
|
148
155
|
@deprecated
|
|
@@ -161,53 +168,22 @@ if (macroCondition(getOwnConfig().deprecations.DEPRECATE_SNAPSHOT_MODEL_CLASS_AC
|
|
|
161
168
|
enabled: '4.5.0'
|
|
162
169
|
}
|
|
163
170
|
});
|
|
164
|
-
// @ts-expect-error
|
|
165
171
|
return this._recordArray.type;
|
|
166
172
|
}
|
|
167
173
|
});
|
|
168
174
|
}
|
|
169
|
-
function _bind(fn, ...args) {
|
|
170
|
-
return function () {
|
|
171
|
-
return fn.apply(undefined, args);
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
function _guard(promise, test) {
|
|
175
|
-
let guarded = promise.finally(() => {
|
|
176
|
-
if (!test()) {
|
|
177
|
-
guarded._subscribers ? guarded._subscribers.length = 0 : null;
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
return guarded;
|
|
181
|
-
}
|
|
182
|
-
function _objectIsAlive(object) {
|
|
183
|
-
return !(object.isDestroyed || object.isDestroying);
|
|
184
|
-
}
|
|
185
|
-
function guardDestroyedStore(promise, store) {
|
|
186
|
-
return promise.then(_v => {
|
|
187
|
-
if (!_objectIsAlive(store)) {
|
|
188
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RSVP_PROMISE)) {
|
|
189
|
-
deprecate(`A Promise did not resolve by the time the store was destroyed. This will error in a future release.`, false, {
|
|
190
|
-
id: 'ember-data:rsvp-unresolved-async',
|
|
191
|
-
until: '5.0',
|
|
192
|
-
for: '@ember-data/store',
|
|
193
|
-
since: {
|
|
194
|
-
available: '4.5',
|
|
195
|
-
enabled: '4.5'
|
|
196
|
-
}
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
return _v;
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
175
|
function assertIdentifierHasId(identifier) {
|
|
204
|
-
|
|
176
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
177
|
+
if (!test) {
|
|
178
|
+
throw new Error(`Attempted to schedule a fetch for a record without an id.`);
|
|
179
|
+
}
|
|
180
|
+
})(identifier && identifier.id !== null) : {};
|
|
205
181
|
}
|
|
206
182
|
function iterateData(data, fn) {
|
|
207
183
|
if (Array.isArray(data)) {
|
|
208
184
|
return data.map(fn);
|
|
209
185
|
} else {
|
|
210
|
-
return fn(data);
|
|
186
|
+
return fn(data, 0);
|
|
211
187
|
}
|
|
212
188
|
}
|
|
213
189
|
function payloadIsNotBlank(adapterPayload) {
|
|
@@ -227,8 +203,8 @@ function payloadIsNotBlank(adapterPayload) {
|
|
|
227
203
|
@internal
|
|
228
204
|
*/
|
|
229
205
|
function validateDocumentStructure(doc) {
|
|
230
|
-
if (macroCondition(
|
|
231
|
-
|
|
206
|
+
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
207
|
+
const errors = [];
|
|
232
208
|
if (!doc || typeof doc !== 'object') {
|
|
233
209
|
errors.push('Top level of a JSON API document must be an object');
|
|
234
210
|
} else {
|
|
@@ -270,11 +246,15 @@ function validateDocumentStructure(doc) {
|
|
|
270
246
|
}
|
|
271
247
|
}
|
|
272
248
|
}
|
|
273
|
-
|
|
249
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
250
|
+
if (!test) {
|
|
251
|
+
throw new Error(`Response must be normalized to a valid JSON API document:\n\t* ${errors.join('\n\t* ')}`);
|
|
252
|
+
}
|
|
253
|
+
})(errors.length === 0) : {};
|
|
274
254
|
}
|
|
275
255
|
}
|
|
276
256
|
function normalizeResponseHelper(serializer, store, modelClass, payload, id, requestType) {
|
|
277
|
-
|
|
257
|
+
const normalizedResponse = serializer ? serializer.normalizeResponse(store, modelClass, payload, id, requestType) : payload;
|
|
278
258
|
validateDocumentStructure(normalizedResponse);
|
|
279
259
|
return normalizedResponse;
|
|
280
260
|
}
|
|
@@ -294,6 +274,14 @@ function normalizeResponseHelper(serializer, store, modelClass, payload, id, req
|
|
|
294
274
|
@public
|
|
295
275
|
*/
|
|
296
276
|
class Snapshot {
|
|
277
|
+
/**
|
|
278
|
+
The type of the underlying record for this snapshot, as a Model.
|
|
279
|
+
@property type
|
|
280
|
+
@public
|
|
281
|
+
@deprecated
|
|
282
|
+
@type {Model}
|
|
283
|
+
*/
|
|
284
|
+
|
|
297
285
|
/**
|
|
298
286
|
* @method constructor
|
|
299
287
|
* @constructor
|
|
@@ -309,10 +297,7 @@ class Snapshot {
|
|
|
309
297
|
this._belongsToIds = Object.create(null);
|
|
310
298
|
this._hasManyRelationships = Object.create(null);
|
|
311
299
|
this._hasManyIds = Object.create(null);
|
|
312
|
-
const hasRecord = !!store._instanceCache.peek(
|
|
313
|
-
identifier,
|
|
314
|
-
bucket: 'record'
|
|
315
|
-
});
|
|
300
|
+
const hasRecord = !!store._instanceCache.peek(identifier);
|
|
316
301
|
this.modelName = identifier.type;
|
|
317
302
|
|
|
318
303
|
/**
|
|
@@ -331,6 +316,7 @@ class Snapshot {
|
|
|
331
316
|
the values.
|
|
332
317
|
*/
|
|
333
318
|
if (hasRecord) {
|
|
319
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
334
320
|
this._attributes;
|
|
335
321
|
}
|
|
336
322
|
|
|
@@ -372,7 +358,7 @@ class Snapshot {
|
|
|
372
358
|
*/
|
|
373
359
|
this.modelName = identifier.type;
|
|
374
360
|
if (hasRecord) {
|
|
375
|
-
const cache =
|
|
361
|
+
const cache = this._store.cache;
|
|
376
362
|
this._changedAttributes = cache.changedAttrs(identifier);
|
|
377
363
|
}
|
|
378
364
|
}
|
|
@@ -390,7 +376,11 @@ class Snapshot {
|
|
|
390
376
|
*/
|
|
391
377
|
get record() {
|
|
392
378
|
const record = this._store.peekRecord(this.identifier);
|
|
393
|
-
|
|
379
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
380
|
+
if (!test) {
|
|
381
|
+
throw new Error(`Record ${this.identifier.type} ${this.identifier.id} (${this.identifier.lid}) is not yet loaded and thus cannot be accessed from the Snapshot during serialization`);
|
|
382
|
+
}
|
|
383
|
+
})(record !== null) : {};
|
|
394
384
|
return record;
|
|
395
385
|
}
|
|
396
386
|
get _attributes() {
|
|
@@ -401,27 +391,17 @@ class Snapshot {
|
|
|
401
391
|
const {
|
|
402
392
|
identifier
|
|
403
393
|
} = this;
|
|
404
|
-
const attrs =
|
|
405
|
-
const cache =
|
|
406
|
-
attrs.forEach(keyName => {
|
|
407
|
-
|
|
394
|
+
const attrs = this._store.schema.fields(identifier);
|
|
395
|
+
const cache = this._store.cache;
|
|
396
|
+
attrs.forEach((field, keyName) => {
|
|
397
|
+
if (field.kind === 'attribute') {
|
|
398
|
+
attributes[keyName] = cache.getAttr(identifier, keyName);
|
|
399
|
+
}
|
|
408
400
|
});
|
|
409
401
|
return attributes;
|
|
410
402
|
}
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
The type of the underlying record for this snapshot, as a Model.
|
|
414
|
-
@property type
|
|
415
|
-
@public
|
|
416
|
-
@deprecated
|
|
417
|
-
@type {Model}
|
|
418
|
-
*/
|
|
419
|
-
|
|
420
403
|
get isNew() {
|
|
421
|
-
const cache =
|
|
422
|
-
identifier: this.identifier,
|
|
423
|
-
bucket: 'resourceCache'
|
|
424
|
-
}) : this._store.cache;
|
|
404
|
+
const cache = this._store.cache;
|
|
425
405
|
return cache?.isNew(this.identifier) || false;
|
|
426
406
|
}
|
|
427
407
|
|
|
@@ -443,7 +423,11 @@ class Snapshot {
|
|
|
443
423
|
if (keyName in this._attributes) {
|
|
444
424
|
return this._attributes[keyName];
|
|
445
425
|
}
|
|
446
|
-
|
|
426
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
427
|
+
{
|
|
428
|
+
throw new Error(`Model '${this.identifier.lid}' has no attribute named '${keyName}' defined.`);
|
|
429
|
+
}
|
|
430
|
+
})() : {};
|
|
447
431
|
}
|
|
448
432
|
|
|
449
433
|
/**
|
|
@@ -476,13 +460,13 @@ class Snapshot {
|
|
|
476
460
|
@public
|
|
477
461
|
*/
|
|
478
462
|
changedAttributes() {
|
|
479
|
-
|
|
463
|
+
const changedAttributes = Object.create(null);
|
|
480
464
|
if (!this._changedAttributes) {
|
|
481
465
|
return changedAttributes;
|
|
482
466
|
}
|
|
483
|
-
|
|
467
|
+
const changedAttributeKeys = Object.keys(this._changedAttributes);
|
|
484
468
|
for (let i = 0, length = changedAttributeKeys.length; i < length; i++) {
|
|
485
|
-
|
|
469
|
+
const key = changedAttributeKeys[i];
|
|
486
470
|
changedAttributes[key] = this._changedAttributes[key].slice();
|
|
487
471
|
}
|
|
488
472
|
return changedAttributes;
|
|
@@ -517,40 +501,50 @@ class Snapshot {
|
|
|
517
501
|
will be returned if the contents of the relationship is unknown.
|
|
518
502
|
*/
|
|
519
503
|
belongsTo(keyName, options) {
|
|
520
|
-
|
|
504
|
+
const returnModeIsId = !!(options && options.id);
|
|
521
505
|
let result;
|
|
522
|
-
|
|
506
|
+
const store = this._store;
|
|
523
507
|
if (returnModeIsId === true && keyName in this._belongsToIds) {
|
|
524
508
|
return this._belongsToIds[keyName];
|
|
525
509
|
}
|
|
526
510
|
if (returnModeIsId === false && keyName in this._belongsToRelationships) {
|
|
527
511
|
return this._belongsToRelationships[keyName];
|
|
528
512
|
}
|
|
529
|
-
|
|
513
|
+
const relationshipMeta = store.schema.fields({
|
|
530
514
|
type: this.modelName
|
|
531
|
-
})
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
}
|
|
515
|
+
}).get(keyName);
|
|
516
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
517
|
+
if (!test) {
|
|
518
|
+
throw new Error(`Model '${this.identifier.lid}' has no belongsTo relationship named '${keyName}' defined.`);
|
|
519
|
+
}
|
|
520
|
+
})(relationshipMeta && relationshipMeta.kind === 'belongsTo') : {};
|
|
521
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
522
|
+
if (!test) {
|
|
523
|
+
throw new Error(`snapshot.belongsTo only supported when using the package @ember-data/graph`);
|
|
524
|
+
}
|
|
525
|
+
})(dependencySatisfies('@ember-data/graph', '*')) : {};
|
|
542
526
|
const graphFor = importSync('@ember-data/graph/-private').graphFor;
|
|
543
527
|
const {
|
|
544
528
|
identifier
|
|
545
529
|
} = this;
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
530
|
+
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
531
|
+
const relationship = graphFor(this._store).get(identifier, keyName);
|
|
532
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
533
|
+
if (!test) {
|
|
534
|
+
throw new Error(`You looked up the ${keyName} belongsTo relationship for { type: ${identifier.type}, id: ${identifier.id || ''}, lid: ${identifier.lid} but no such relationship was found.`);
|
|
535
|
+
}
|
|
536
|
+
})(relationship) : {};
|
|
537
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
538
|
+
if (!test) {
|
|
539
|
+
throw new Error(`You looked up the ${keyName} belongsTo relationship for { type: ${identifier.type}, id: ${identifier.id || ''}, lid: ${identifier.lid} but that relationship is a hasMany.`);
|
|
540
|
+
}
|
|
541
|
+
})(relationship.definition.kind === 'belongsTo') : {};
|
|
542
|
+
}
|
|
543
|
+
const value = graphFor(this._store).getData(identifier, keyName);
|
|
544
|
+
const data = value && value.data;
|
|
545
|
+
const inverseIdentifier = data ? store.identifierCache.getOrCreateRecordIdentifier(data) : null;
|
|
552
546
|
if (value && value.data !== undefined) {
|
|
553
|
-
const cache =
|
|
547
|
+
const cache = store.cache;
|
|
554
548
|
if (inverseIdentifier && !cache.isDeleted(inverseIdentifier)) {
|
|
555
549
|
if (returnModeIsId) {
|
|
556
550
|
result = inverseIdentifier.id;
|
|
@@ -593,43 +587,59 @@ class Snapshot {
|
|
|
593
587
|
undefined will be returned if the contents of the relationship is unknown.
|
|
594
588
|
*/
|
|
595
589
|
hasMany(keyName, options) {
|
|
596
|
-
|
|
590
|
+
const returnModeIsIds = !!(options && options.ids);
|
|
597
591
|
let results;
|
|
598
|
-
|
|
599
|
-
|
|
592
|
+
const cachedIds = this._hasManyIds[keyName];
|
|
593
|
+
const cachedSnapshots = this._hasManyRelationships[keyName];
|
|
600
594
|
if (returnModeIsIds === true && keyName in this._hasManyIds) {
|
|
601
595
|
return cachedIds;
|
|
602
596
|
}
|
|
603
597
|
if (returnModeIsIds === false && keyName in this._hasManyRelationships) {
|
|
604
598
|
return cachedSnapshots;
|
|
605
599
|
}
|
|
606
|
-
|
|
607
|
-
|
|
600
|
+
const store = this._store;
|
|
601
|
+
const relationshipMeta = store.schema.fields({
|
|
608
602
|
type: this.modelName
|
|
609
|
-
})
|
|
610
|
-
|
|
603
|
+
}).get(keyName);
|
|
604
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
605
|
+
if (!test) {
|
|
606
|
+
throw new Error(`Model '${this.identifier.lid}' has no hasMany relationship named '${keyName}' defined.`);
|
|
607
|
+
}
|
|
608
|
+
})(relationshipMeta && relationshipMeta.kind === 'hasMany') : {};
|
|
611
609
|
|
|
612
610
|
// TODO @runspired it seems this code branch would not work with CUSTOM_MODEL_CLASSes
|
|
613
611
|
// this check is not a regression in behavior because relationships don't currently
|
|
614
612
|
// function without access to intimate API contracts between RecordData and Model.
|
|
615
613
|
// This is a requirement we should fix as soon as the relationship layer does not require
|
|
616
614
|
// this intimate API usage.
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
615
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
616
|
+
if (!test) {
|
|
617
|
+
throw new Error(`snapshot.hasMany only supported when using the package @ember-data/graph`);
|
|
618
|
+
}
|
|
619
|
+
})(dependencySatisfies('@ember-data/graph', '*')) : {};
|
|
620
620
|
const graphFor = importSync('@ember-data/graph/-private').graphFor;
|
|
621
621
|
const {
|
|
622
622
|
identifier
|
|
623
623
|
} = this;
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
624
|
+
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
625
|
+
const relationship = graphFor(this._store).get(identifier, keyName);
|
|
626
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
627
|
+
if (!test) {
|
|
628
|
+
throw new Error(`You looked up the ${keyName} hasMany relationship for { type: ${identifier.type}, id: ${identifier.id || ''}, lid: ${identifier.lid} but no such relationship was found.`);
|
|
629
|
+
}
|
|
630
|
+
})(relationship) : {};
|
|
631
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
632
|
+
if (!test) {
|
|
633
|
+
throw new Error(`You looked up the ${keyName} hasMany relationship for { type: ${identifier.type}, id: ${identifier.id || ''}, lid: ${identifier.lid} but that relationship is a belongsTo.`);
|
|
634
|
+
}
|
|
635
|
+
})(relationship.definition.kind === 'hasMany') : {};
|
|
636
|
+
}
|
|
637
|
+
const value = graphFor(this._store).getData(identifier, keyName);
|
|
628
638
|
if (value.data) {
|
|
629
639
|
results = [];
|
|
630
640
|
value.data.forEach(member => {
|
|
631
|
-
|
|
632
|
-
const cache =
|
|
641
|
+
const inverseIdentifier = store.identifierCache.getOrCreateRecordIdentifier(member);
|
|
642
|
+
const cache = store.cache;
|
|
633
643
|
if (!cache.isDeleted(inverseIdentifier)) {
|
|
634
644
|
if (returnModeIsIds) {
|
|
635
645
|
results.push(inverseIdentifier.id);
|
|
@@ -665,9 +675,11 @@ class Snapshot {
|
|
|
665
675
|
@public
|
|
666
676
|
*/
|
|
667
677
|
eachAttribute(callback, binding) {
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
678
|
+
const fields = this._store.schema.fields(this.identifier);
|
|
679
|
+
fields.forEach((field, key) => {
|
|
680
|
+
if (field.kind === 'attribute') {
|
|
681
|
+
callback.call(binding, key, field);
|
|
682
|
+
}
|
|
671
683
|
});
|
|
672
684
|
}
|
|
673
685
|
|
|
@@ -686,9 +698,11 @@ class Snapshot {
|
|
|
686
698
|
@public
|
|
687
699
|
*/
|
|
688
700
|
eachRelationship(callback, binding) {
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
701
|
+
const fields = this._store.schema.fields(this.identifier);
|
|
702
|
+
fields.forEach((field, key) => {
|
|
703
|
+
if (field.kind === 'belongsTo' || field.kind === 'hasMany') {
|
|
704
|
+
callback.call(binding, key, field);
|
|
705
|
+
}
|
|
692
706
|
});
|
|
693
707
|
}
|
|
694
708
|
|
|
@@ -714,12 +728,17 @@ class Snapshot {
|
|
|
714
728
|
@public
|
|
715
729
|
*/
|
|
716
730
|
serialize(options) {
|
|
731
|
+
upgradeStore(this._store);
|
|
717
732
|
const serializer = this._store.serializerFor(this.modelName);
|
|
718
|
-
|
|
733
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
734
|
+
if (!test) {
|
|
735
|
+
throw new Error(`Cannot serialize record, no serializer found`);
|
|
736
|
+
}
|
|
737
|
+
})(serializer) : {};
|
|
719
738
|
return serializer.serialize(this, options);
|
|
720
739
|
}
|
|
721
740
|
}
|
|
722
|
-
if (macroCondition(
|
|
741
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_SNAPSHOT_MODEL_CLASS_ACCESS)) {
|
|
723
742
|
Object.defineProperty(Snapshot.prototype, 'type', {
|
|
724
743
|
get() {
|
|
725
744
|
deprecate(`Using Snapshot.type to access the ModelClass for a record is deprecated. Use store.modelFor(<modelName>) instead.`, false, {
|
|
@@ -735,7 +754,47 @@ if (macroCondition(getOwnConfig().deprecations.DEPRECATE_SNAPSHOT_MODEL_CLASS_AC
|
|
|
735
754
|
}
|
|
736
755
|
});
|
|
737
756
|
}
|
|
738
|
-
|
|
757
|
+
function isObject(value) {
|
|
758
|
+
return value !== null && typeof value === 'object';
|
|
759
|
+
}
|
|
760
|
+
function _objectIsAlive(object) {
|
|
761
|
+
return isObject(object) ? !(object.isDestroyed || object.isDestroying) : false;
|
|
762
|
+
}
|
|
763
|
+
function guardDestroyedStore(promise, store) {
|
|
764
|
+
return promise.then(_v => {
|
|
765
|
+
if (!_objectIsAlive(store)) {
|
|
766
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_RSVP_PROMISE)) {
|
|
767
|
+
deprecate(`A Promise did not resolve by the time the store was destroyed. This will error in a future release.`, false, {
|
|
768
|
+
id: 'ember-data:rsvp-unresolved-async',
|
|
769
|
+
until: '5.0',
|
|
770
|
+
for: '@ember-data/store',
|
|
771
|
+
since: {
|
|
772
|
+
available: '4.5',
|
|
773
|
+
enabled: '4.5'
|
|
774
|
+
}
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
return _v;
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
function _bind(fn, ...args) {
|
|
782
|
+
return function () {
|
|
783
|
+
// eslint-disable-next-line prefer-spread
|
|
784
|
+
return fn.apply(undefined, args);
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
function _guard(promise, test) {
|
|
788
|
+
const guarded = promise.finally(() => {
|
|
789
|
+
if (!test()) {
|
|
790
|
+
// @ts-expect-error this is a private RSVPPromise API that won't always be there
|
|
791
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions, @typescript-eslint/no-unsafe-member-access
|
|
792
|
+
guarded._subscribers ? guarded._subscribers.length = 0 : null;
|
|
793
|
+
}
|
|
794
|
+
});
|
|
795
|
+
return guarded;
|
|
796
|
+
}
|
|
797
|
+
const SaveOp = getOrSetGlobal('SaveOp', Symbol('SaveOp'));
|
|
739
798
|
class FetchManager {
|
|
740
799
|
// fetches pending in the runloop, waiting to be coalesced
|
|
741
800
|
|
|
@@ -757,13 +816,13 @@ class FetchManager {
|
|
|
757
816
|
@internal
|
|
758
817
|
*/
|
|
759
818
|
scheduleSave(identifier, options) {
|
|
760
|
-
|
|
761
|
-
|
|
819
|
+
const resolver = createDeferred();
|
|
820
|
+
const query = {
|
|
762
821
|
op: 'saveRecord',
|
|
763
822
|
recordIdentifier: identifier,
|
|
764
823
|
options
|
|
765
824
|
};
|
|
766
|
-
|
|
825
|
+
const queryRequest = {
|
|
767
826
|
data: [query]
|
|
768
827
|
};
|
|
769
828
|
const snapshot = this.createSnapshot(identifier, options);
|
|
@@ -779,19 +838,19 @@ class FetchManager {
|
|
|
779
838
|
return monitored;
|
|
780
839
|
}
|
|
781
840
|
scheduleFetch(identifier, options, request) {
|
|
782
|
-
|
|
841
|
+
const query = {
|
|
783
842
|
op: 'findRecord',
|
|
784
843
|
recordIdentifier: identifier,
|
|
785
844
|
options
|
|
786
845
|
};
|
|
787
|
-
|
|
846
|
+
const queryRequest = {
|
|
788
847
|
data: [query]
|
|
789
848
|
};
|
|
790
|
-
|
|
849
|
+
const pendingFetch = this.getPendingFetch(identifier, options);
|
|
791
850
|
if (pendingFetch) {
|
|
792
851
|
return pendingFetch;
|
|
793
852
|
}
|
|
794
|
-
|
|
853
|
+
const modelName = identifier.type;
|
|
795
854
|
const resolver = createDeferred();
|
|
796
855
|
const pendingFetchItem = {
|
|
797
856
|
identifier,
|
|
@@ -799,7 +858,7 @@ class FetchManager {
|
|
|
799
858
|
options,
|
|
800
859
|
queryRequest
|
|
801
860
|
};
|
|
802
|
-
|
|
861
|
+
const resolverPromise = resolver.promise;
|
|
803
862
|
const store = this._store;
|
|
804
863
|
const isInitialLoad = !store._instanceCache.recordIsLoaded(identifier); // we don't use isLoading directly because we are the request
|
|
805
864
|
|
|
@@ -812,20 +871,21 @@ class FetchManager {
|
|
|
812
871
|
|
|
813
872
|
// additional data received in the payload
|
|
814
873
|
// may result in the merging of identifiers (and thus records)
|
|
815
|
-
|
|
874
|
+
const potentiallyNewIm = store._push(payload, options.reload);
|
|
816
875
|
if (potentiallyNewIm && !Array.isArray(potentiallyNewIm)) {
|
|
817
876
|
return potentiallyNewIm;
|
|
818
877
|
}
|
|
819
878
|
return identifier;
|
|
820
879
|
}, error => {
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
}) :
|
|
880
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
881
|
+
if (!test) {
|
|
882
|
+
throw new Error(`Async Leak Detected: Expected the store to not be destroyed`);
|
|
883
|
+
}
|
|
884
|
+
})(!store.isDestroyed) : {};
|
|
885
|
+
const cache = store.cache;
|
|
826
886
|
if (!cache || cache.isEmpty(identifier) || isInitialLoad) {
|
|
827
887
|
let isReleasable = true;
|
|
828
|
-
if (macroCondition(
|
|
888
|
+
if (macroCondition(dependencySatisfies('@ember-data/graph', '*'))) {
|
|
829
889
|
if (!cache) {
|
|
830
890
|
const graphFor = importSync('@ember-data/graph/-private').graphFor;
|
|
831
891
|
const graph = graphFor(store);
|
|
@@ -848,7 +908,7 @@ class FetchManager {
|
|
|
848
908
|
this.flushAllPendingFetches();
|
|
849
909
|
});
|
|
850
910
|
}
|
|
851
|
-
|
|
911
|
+
const fetchesByType = this._pendingFetch;
|
|
852
912
|
let fetchesById = fetchesByType.get(modelName);
|
|
853
913
|
if (!fetchesById) {
|
|
854
914
|
fetchesById = new Map();
|
|
@@ -860,7 +920,7 @@ class FetchManager {
|
|
|
860
920
|
fetchesById.set(identifier, requestsForIdentifier);
|
|
861
921
|
}
|
|
862
922
|
requestsForIdentifier.push(pendingFetchItem);
|
|
863
|
-
if (macroCondition(
|
|
923
|
+
if (macroCondition(getGlobalConfig().WarpDrive.env.TESTING)) {
|
|
864
924
|
if (!request.disableTestWaiter) {
|
|
865
925
|
const {
|
|
866
926
|
waitForPromise
|
|
@@ -872,11 +932,11 @@ class FetchManager {
|
|
|
872
932
|
return promise;
|
|
873
933
|
}
|
|
874
934
|
getPendingFetch(identifier, options) {
|
|
875
|
-
|
|
935
|
+
const pendingFetches = this._pendingFetch.get(identifier.type)?.get(identifier);
|
|
876
936
|
|
|
877
937
|
// We already have a pending fetch for this
|
|
878
938
|
if (pendingFetches) {
|
|
879
|
-
|
|
939
|
+
const matchingPendingFetch = pendingFetches.find(fetch => isSameRequest(options, fetch.options));
|
|
880
940
|
if (matchingPendingFetch) {
|
|
881
941
|
return matchingPendingFetch.promise;
|
|
882
942
|
}
|
|
@@ -897,7 +957,7 @@ class FetchManager {
|
|
|
897
957
|
let promise;
|
|
898
958
|
if (isEmpty) {
|
|
899
959
|
assertIdentifierHasId(identifier);
|
|
900
|
-
if (macroCondition(
|
|
960
|
+
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
901
961
|
promise = this.scheduleFetch(identifier, Object.assign({}, options, {
|
|
902
962
|
reload: true
|
|
903
963
|
}), request);
|
|
@@ -907,7 +967,11 @@ class FetchManager {
|
|
|
907
967
|
}
|
|
908
968
|
} else if (isLoading) {
|
|
909
969
|
promise = this.getPendingFetch(identifier, options);
|
|
910
|
-
|
|
970
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
971
|
+
if (!test) {
|
|
972
|
+
throw new Error(`Expected to find a pending request for a record in the loading state, but found none`);
|
|
973
|
+
}
|
|
974
|
+
})(promise) : {};
|
|
911
975
|
} else {
|
|
912
976
|
promise = Promise.resolve(identifier);
|
|
913
977
|
}
|
|
@@ -918,7 +982,7 @@ class FetchManager {
|
|
|
918
982
|
}
|
|
919
983
|
}
|
|
920
984
|
function _isEmpty(instanceCache, identifier) {
|
|
921
|
-
const cache =
|
|
985
|
+
const cache = instanceCache.cache;
|
|
922
986
|
if (!cache) {
|
|
923
987
|
return true;
|
|
924
988
|
}
|
|
@@ -933,7 +997,7 @@ function _isLoading(cache, identifier) {
|
|
|
933
997
|
const isLoaded = cache.recordIsLoaded(identifier);
|
|
934
998
|
return !isLoaded &&
|
|
935
999
|
// fulfilled === null &&
|
|
936
|
-
req.getPendingRequestsForRecord(identifier).some(
|
|
1000
|
+
req.getPendingRequestsForRecord(identifier).some(r => r.type === 'query');
|
|
937
1001
|
}
|
|
938
1002
|
function includesSatisfies(current, existing) {
|
|
939
1003
|
// if we have no includes we are good
|
|
@@ -972,28 +1036,43 @@ function isSameRequest(options = {}, existingOptions = {}) {
|
|
|
972
1036
|
return optionsSatisfies(options.adapterOptions, existingOptions.adapterOptions) && includesSatisfies(options.include, existingOptions.include);
|
|
973
1037
|
}
|
|
974
1038
|
function _findMany(store, adapter, modelName, snapshots) {
|
|
975
|
-
|
|
976
|
-
|
|
1039
|
+
const modelClass = store.modelFor(modelName); // `adapter.findMany` gets the modelClass still
|
|
1040
|
+
const promise = Promise.resolve().then(() => {
|
|
977
1041
|
const ids = snapshots.map(s => s.id);
|
|
978
|
-
|
|
1042
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1043
|
+
if (!test) {
|
|
1044
|
+
throw new Error(`Cannot fetch a record without an id`);
|
|
1045
|
+
}
|
|
1046
|
+
})(ids.every(v => v !== null)) : {};
|
|
979
1047
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
1048
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1049
|
+
if (!test) {
|
|
1050
|
+
throw new Error(`Expected this adapter to implement findMany for coalescing`);
|
|
1051
|
+
}
|
|
1052
|
+
})(adapter.findMany) : {};
|
|
1053
|
+
const ret = adapter.findMany(store, modelClass, ids, snapshots);
|
|
1054
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1055
|
+
if (!test) {
|
|
1056
|
+
throw new Error('adapter.findMany returned undefined, this was very likely a mistake');
|
|
1057
|
+
}
|
|
1058
|
+
})(ret !== undefined) : {};
|
|
983
1059
|
return ret;
|
|
984
1060
|
});
|
|
985
|
-
promise = guardDestroyedStore(promise, store);
|
|
986
1061
|
return promise.then(adapterPayload => {
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
1062
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1063
|
+
if (!test) {
|
|
1064
|
+
throw new Error(`You made a 'findMany' request for '${modelName}' records with ids '[${snapshots.map(s => s.id).join(',')}]', but the adapter's response did not have any data`);
|
|
1065
|
+
}
|
|
1066
|
+
})(!!payloadIsNotBlank(adapterPayload)) : {};
|
|
1067
|
+
const serializer = store.serializerFor(modelName);
|
|
1068
|
+
const payload = normalizeResponseHelper(serializer, store, modelClass, adapterPayload, null, 'findMany');
|
|
990
1069
|
return payload;
|
|
991
1070
|
});
|
|
992
1071
|
}
|
|
993
1072
|
function rejectFetchedItems(fetchMap, snapshots, error) {
|
|
994
1073
|
for (let i = 0, l = snapshots.length; i < l; i++) {
|
|
995
|
-
|
|
996
|
-
|
|
1074
|
+
const snapshot = snapshots[i];
|
|
1075
|
+
const pair = fetchMap.get(snapshot);
|
|
997
1076
|
if (pair) {
|
|
998
1077
|
pair.resolver.reject(error || new Error(`Expected: '<${snapshot.modelName}:${snapshot.id}>' to be present in the adapter provided payload, but it was not found.`));
|
|
999
1078
|
}
|
|
@@ -1009,9 +1088,9 @@ function handleFoundRecords(store, fetchMap, snapshots, coalescedPayload) {
|
|
|
1009
1088
|
options object, we resolve all snapshots by id with
|
|
1010
1089
|
the first response we see.
|
|
1011
1090
|
*/
|
|
1012
|
-
|
|
1091
|
+
const snapshotsById = new Map();
|
|
1013
1092
|
for (let i = 0; i < snapshots.length; i++) {
|
|
1014
|
-
|
|
1093
|
+
const id = snapshots[i].id;
|
|
1015
1094
|
let snapshotGroup = snapshotsById.get(id);
|
|
1016
1095
|
if (!snapshotGroup) {
|
|
1017
1096
|
snapshotGroup = [];
|
|
@@ -1022,18 +1101,18 @@ function handleFoundRecords(store, fetchMap, snapshots, coalescedPayload) {
|
|
|
1022
1101
|
const included = Array.isArray(coalescedPayload.included) ? coalescedPayload.included : [];
|
|
1023
1102
|
|
|
1024
1103
|
// resolve found records
|
|
1025
|
-
|
|
1104
|
+
const resources = coalescedPayload.data;
|
|
1026
1105
|
for (let i = 0, l = resources.length; i < l; i++) {
|
|
1027
|
-
|
|
1028
|
-
|
|
1106
|
+
const resource = resources[i];
|
|
1107
|
+
const snapshotGroup = snapshotsById.get(resource.id);
|
|
1029
1108
|
snapshotsById.delete(resource.id);
|
|
1030
1109
|
if (!snapshotGroup) {
|
|
1031
1110
|
// TODO consider whether this should be a deprecation/assertion
|
|
1032
1111
|
included.push(resource);
|
|
1033
1112
|
} else {
|
|
1034
1113
|
snapshotGroup.forEach(snapshot => {
|
|
1035
|
-
|
|
1036
|
-
|
|
1114
|
+
const pair = fetchMap.get(snapshot);
|
|
1115
|
+
const resolver = pair.resolver;
|
|
1037
1116
|
resolver.resolve({
|
|
1038
1117
|
data: resource
|
|
1039
1118
|
});
|
|
@@ -1051,9 +1130,9 @@ function handleFoundRecords(store, fetchMap, snapshots, coalescedPayload) {
|
|
|
1051
1130
|
}
|
|
1052
1131
|
|
|
1053
1132
|
// reject missing records
|
|
1054
|
-
|
|
1055
|
-
snapshotsById.forEach(
|
|
1056
|
-
rejected.push(...
|
|
1133
|
+
const rejected = [];
|
|
1134
|
+
snapshotsById.forEach(snapshotArray => {
|
|
1135
|
+
rejected.push(...snapshotArray);
|
|
1057
1136
|
});
|
|
1058
1137
|
warn('Ember Data expected to find records with the following ids in the adapter response from findMany but they were missing: [ "' + [...snapshotsById.values()].map(r => r[0].id).join('", "') + '" ]', {
|
|
1059
1138
|
id: 'ds.store.missing-records-from-adapter'
|
|
@@ -1061,23 +1140,47 @@ function handleFoundRecords(store, fetchMap, snapshots, coalescedPayload) {
|
|
|
1061
1140
|
rejectFetchedItems(fetchMap, rejected);
|
|
1062
1141
|
}
|
|
1063
1142
|
function _fetchRecord(store, adapter, fetchItem) {
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1143
|
+
const identifier = fetchItem.identifier;
|
|
1144
|
+
const modelName = identifier.type;
|
|
1145
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1146
|
+
if (!test) {
|
|
1147
|
+
throw new Error(`You tried to find a record but you have no adapter (for ${modelName})`);
|
|
1148
|
+
}
|
|
1149
|
+
})(adapter) : {};
|
|
1150
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1151
|
+
if (!test) {
|
|
1152
|
+
throw new Error(`You tried to find a record but your adapter (for ${modelName}) does not implement 'findRecord'`);
|
|
1153
|
+
}
|
|
1154
|
+
})(typeof adapter.findRecord === 'function') : {};
|
|
1155
|
+
const snapshot = store._fetchManager.createSnapshot(identifier, fetchItem.options);
|
|
1156
|
+
const klass = store.modelFor(identifier.type);
|
|
1157
|
+
const id = identifier.id;
|
|
1071
1158
|
let promise = Promise.resolve().then(() => {
|
|
1072
1159
|
return adapter.findRecord(store, klass, identifier.id, snapshot);
|
|
1073
1160
|
});
|
|
1074
1161
|
promise = promise.then(adapterPayload => {
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1162
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1163
|
+
if (!test) {
|
|
1164
|
+
throw new Error(`Async Leak Detected: Expected the store to not be destroyed`);
|
|
1165
|
+
}
|
|
1166
|
+
})(!(store.isDestroyed || store.isDestroying)) : {};
|
|
1167
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1168
|
+
if (!test) {
|
|
1169
|
+
throw new Error(`You made a 'findRecord' request for a '${modelName}' with id '${id}', but the adapter's response did not have any data`);
|
|
1170
|
+
}
|
|
1171
|
+
})(!!payloadIsNotBlank(adapterPayload)) : {};
|
|
1172
|
+
const serializer = store.serializerFor(modelName);
|
|
1173
|
+
const payload = normalizeResponseHelper(serializer, store, klass, adapterPayload, id, 'findRecord');
|
|
1174
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1175
|
+
if (!test) {
|
|
1176
|
+
throw new Error(`Ember Data expected the primary data returned from a 'findRecord' response to be an object but instead it found an array.`);
|
|
1177
|
+
}
|
|
1178
|
+
})(!Array.isArray(payload.data)) : {};
|
|
1179
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1180
|
+
if (!test) {
|
|
1181
|
+
throw new Error(`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.`);
|
|
1182
|
+
}
|
|
1183
|
+
})('data' in payload && payload.data !== null && typeof payload.data === 'object') : {};
|
|
1081
1184
|
warn(`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.`, coerceId(payload.data.id) === coerceId(id), {
|
|
1082
1185
|
id: 'ds.store.findRecord.id-mismatch'
|
|
1083
1186
|
});
|
|
@@ -1095,12 +1198,16 @@ function _processCoalescedGroup(store, fetchMap, group, adapter, modelName) {
|
|
|
1095
1198
|
} else if (group.length === 1) {
|
|
1096
1199
|
_fetchRecord(store, adapter, fetchMap.get(group[0]));
|
|
1097
1200
|
} else {
|
|
1098
|
-
|
|
1201
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1202
|
+
{
|
|
1203
|
+
throw new Error("You cannot return an empty array from adapter's method groupRecordsForFindMany");
|
|
1204
|
+
}
|
|
1205
|
+
})() : {};
|
|
1099
1206
|
}
|
|
1100
1207
|
}
|
|
1101
1208
|
function _flushPendingFetchForType(store, pendingFetchMap, modelName) {
|
|
1102
|
-
|
|
1103
|
-
|
|
1209
|
+
const adapter = store.adapterFor(modelName);
|
|
1210
|
+
const shouldCoalesce = !!adapter.findMany && adapter.coalesceFindRequests;
|
|
1104
1211
|
if (shouldCoalesce) {
|
|
1105
1212
|
const pendingFetchItems = [];
|
|
1106
1213
|
pendingFetchMap.forEach((requestsForIdentifier, identifier) => {
|
|
@@ -1112,12 +1219,12 @@ function _flushPendingFetchForType(store, pendingFetchMap, modelName) {
|
|
|
1112
1219
|
pendingFetchMap.delete(identifier);
|
|
1113
1220
|
pendingFetchItems.push(requestsForIdentifier[0]);
|
|
1114
1221
|
});
|
|
1115
|
-
|
|
1222
|
+
const totalItems = pendingFetchItems.length;
|
|
1116
1223
|
if (totalItems > 1) {
|
|
1117
|
-
|
|
1118
|
-
|
|
1224
|
+
const snapshots = new Array(totalItems);
|
|
1225
|
+
const fetchMap = new Map();
|
|
1119
1226
|
for (let i = 0; i < totalItems; i++) {
|
|
1120
|
-
|
|
1227
|
+
const fetchItem = pendingFetchItems[i];
|
|
1121
1228
|
snapshots[i] = store._fetchManager.createSnapshot(fetchItem.identifier, fetchItem.options);
|
|
1122
1229
|
fetchMap.set(snapshots[i], fetchItem);
|
|
1123
1230
|
}
|
|
@@ -1131,12 +1238,12 @@ function _flushPendingFetchForType(store, pendingFetchMap, modelName) {
|
|
|
1131
1238
|
_processCoalescedGroup(store, fetchMap, groups[i], adapter, modelName);
|
|
1132
1239
|
}
|
|
1133
1240
|
} else if (totalItems === 1) {
|
|
1134
|
-
|
|
1241
|
+
_fetchRecord(store, adapter, pendingFetchItems[0]);
|
|
1135
1242
|
}
|
|
1136
1243
|
}
|
|
1137
1244
|
pendingFetchMap.forEach(pendingFetchItems => {
|
|
1138
1245
|
pendingFetchItems.forEach(pendingFetchItem => {
|
|
1139
|
-
|
|
1246
|
+
_fetchRecord(store, adapter, pendingFetchItem);
|
|
1140
1247
|
});
|
|
1141
1248
|
});
|
|
1142
1249
|
}
|
|
@@ -1149,18 +1256,29 @@ function _flushPendingSave(store, pending) {
|
|
|
1149
1256
|
} = pending;
|
|
1150
1257
|
const adapter = store.adapterFor(identifier.type);
|
|
1151
1258
|
const operation = options[SaveOp];
|
|
1152
|
-
|
|
1153
|
-
|
|
1259
|
+
const modelName = snapshot.modelName;
|
|
1260
|
+
const modelClass = store.modelFor(modelName);
|
|
1154
1261
|
const record = store._instanceCache.getRecord(identifier);
|
|
1155
|
-
|
|
1156
|
-
|
|
1262
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1263
|
+
if (!test) {
|
|
1264
|
+
throw new Error(`You tried to update a record but you have no adapter (for ${modelName})`);
|
|
1265
|
+
}
|
|
1266
|
+
})(adapter) : {};
|
|
1267
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1268
|
+
if (!test) {
|
|
1269
|
+
throw new Error(`You tried to update a record but your adapter (for ${modelName}) does not implement '${operation}'`);
|
|
1270
|
+
}
|
|
1271
|
+
})(typeof adapter[operation] === 'function') : {};
|
|
1157
1272
|
let promise = Promise.resolve().then(() => adapter[operation](store, modelClass, snapshot));
|
|
1158
|
-
|
|
1159
|
-
|
|
1273
|
+
const serializer = store.serializerFor(modelName);
|
|
1274
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1275
|
+
if (!test) {
|
|
1276
|
+
throw new Error(`Your adapter's '${operation}' method must return a value, but it returned 'undefined'`);
|
|
1277
|
+
}
|
|
1278
|
+
})(promise !== undefined) : {};
|
|
1160
1279
|
promise = promise.then(adapterPayload => {
|
|
1161
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
1162
1280
|
if (!_objectIsAlive(record)) {
|
|
1163
|
-
if (macroCondition(
|
|
1281
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_RSVP_PROMISE)) {
|
|
1164
1282
|
deprecate(`A Promise while saving ${modelName} did not resolve by the time your model was destroyed. This will error in a future release.`, false, {
|
|
1165
1283
|
id: 'ember-data:rsvp-unresolved-async',
|
|
1166
1284
|
until: '5.0',
|
|
@@ -1178,4 +1296,13 @@ function _flushPendingSave(store, pending) {
|
|
|
1178
1296
|
});
|
|
1179
1297
|
resolver.resolve(promise);
|
|
1180
1298
|
}
|
|
1181
|
-
|
|
1299
|
+
|
|
1300
|
+
/**
|
|
1301
|
+
* Utilities - often temporary - for maintaining backwards compatibility with
|
|
1302
|
+
* older parts of EmberData.
|
|
1303
|
+
*
|
|
1304
|
+
@module @ember-data/legacy-compat
|
|
1305
|
+
@main @ember-data/legacy-compat
|
|
1306
|
+
*/
|
|
1307
|
+
function upgradeStore(store) {}
|
|
1308
|
+
export { FetchManager as F, SaveOp as S, _objectIsAlive as _, _guard as a, _bind as b, assertIdentifierHasId as c, SnapshotRecordArray as d, Snapshot as e, guardDestroyedStore as g, iterateData as i, normalizeResponseHelper as n, payloadIsNotBlank as p, upgradeStore as u };
|