@ember-data/store 4.8.0-alpha.4 → 4.8.0-beta.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/-debug/index.js +34 -12
- package/addon/-private/caches/identifier-cache.ts +44 -36
- package/addon/-private/caches/instance-cache.ts +112 -124
- package/addon/-private/caches/record-data-for.ts +1 -6
- package/addon/-private/index.ts +10 -7
- package/addon/-private/legacy-model-support/shim-model-class.ts +11 -8
- package/addon/-private/managers/record-array-manager.ts +282 -326
- package/addon/-private/managers/record-data-manager.ts +143 -128
- package/addon/-private/managers/record-data-store-wrapper.ts +18 -10
- package/addon/-private/managers/record-notification-manager.ts +31 -12
- package/addon/-private/network/fetch-manager.ts +18 -3
- package/addon/-private/network/finders.js +11 -6
- package/addon/-private/network/request-cache.ts +20 -17
- package/addon/-private/network/snapshot-record-array.ts +12 -29
- package/addon/-private/proxies/promise-proxies.ts +72 -11
- package/addon/-private/record-arrays/identifier-array.ts +924 -0
- package/addon/-private/store-service.ts +203 -108
- package/addon/-private/utils/is-non-empty-string.ts +1 -1
- package/addon/-private/utils/promise-record.ts +2 -3
- package/addon/-private/utils/uuid-polyfill.ts +58 -56
- package/package.json +5 -5
- package/addon/-private/backburner.js +0 -25
- package/addon/-private/record-arrays/adapter-populated-record-array.ts +0 -128
- package/addon/-private/record-arrays/record-array.ts +0 -328
- package/addon/-private/utils/weak-cache.ts +0 -125
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
import { getOwner, setOwner } from '@ember/application';
|
|
5
5
|
import { assert, deprecate } from '@ember/debug';
|
|
6
6
|
import { _backburner as emberBackburner, run } from '@ember/runloop';
|
|
7
|
-
import type { Backburner } from '@ember/runloop/-private/backburner';
|
|
8
7
|
import Service from '@ember/service';
|
|
9
8
|
import { registerWaiter, unregisterWaiter } from '@ember/test';
|
|
10
9
|
import { DEBUG } from '@glimmer/env';
|
|
@@ -12,12 +11,12 @@ import { DEBUG } from '@glimmer/env';
|
|
|
12
11
|
import { importSync } from '@embroider/macros';
|
|
13
12
|
import { reject, resolve } from 'rsvp';
|
|
14
13
|
|
|
15
|
-
import { V2CACHE_SINGLETON_RECORD_DATA } from '@ember-data/canary-features';
|
|
16
14
|
import type DSModelClass from '@ember-data/model';
|
|
17
15
|
import { HAS_MODEL_PACKAGE, HAS_RECORD_DATA_PACKAGE } from '@ember-data/private-build-infra';
|
|
18
16
|
import {
|
|
19
17
|
DEPRECATE_HAS_RECORD,
|
|
20
18
|
DEPRECATE_JSON_API_FALLBACK,
|
|
19
|
+
DEPRECATE_PROMISE_PROXIES,
|
|
21
20
|
DEPRECATE_STORE_FIND,
|
|
22
21
|
DEPRECATE_V1CACHE_STORE_APIS,
|
|
23
22
|
} from '@ember-data/private-build-infra/deprecations';
|
|
@@ -41,7 +40,6 @@ import type { SchemaDefinitionService } from '@ember-data/types/q/schema-definit
|
|
|
41
40
|
import type { FindOptions } from '@ember-data/types/q/store';
|
|
42
41
|
import type { Dict } from '@ember-data/types/q/utils';
|
|
43
42
|
|
|
44
|
-
import edBackburner from './backburner';
|
|
45
43
|
import { IdentifierCache } from './caches/identifier-cache';
|
|
46
44
|
import {
|
|
47
45
|
InstanceCache,
|
|
@@ -63,9 +61,10 @@ import NotificationManager from './managers/record-notification-manager';
|
|
|
63
61
|
import FetchManager, { SaveOp } from './network/fetch-manager';
|
|
64
62
|
import { _findAll, _query, _queryRecord } from './network/finders';
|
|
65
63
|
import type RequestCache from './network/request-cache';
|
|
64
|
+
import type Snapshot from './network/snapshot';
|
|
65
|
+
import SnapshotRecordArray from './network/snapshot-record-array';
|
|
66
66
|
import { PromiseArray, promiseArray, PromiseObject, promiseObject } from './proxies/promise-proxies';
|
|
67
|
-
import
|
|
68
|
-
import RecordArray from './record-arrays/record-array';
|
|
67
|
+
import IdentifierArray, { Collection } from './record-arrays/identifier-array';
|
|
69
68
|
import coerceId, { ensureStringId } from './utils/coerce-id';
|
|
70
69
|
import constructResource from './utils/construct-resource';
|
|
71
70
|
import normalizeModelName from './utils/normalize-model-name';
|
|
@@ -167,18 +166,7 @@ export interface CreateRecordProperties {
|
|
|
167
166
|
|
|
168
167
|
class Store extends Service {
|
|
169
168
|
__private_singleton_recordData!: RecordData;
|
|
170
|
-
/**
|
|
171
|
-
* Ember Data uses several specialized micro-queues for organizing
|
|
172
|
-
and coalescing similar async work.
|
|
173
169
|
|
|
174
|
-
These queues are currently controlled by a flush scheduled into
|
|
175
|
-
ember-data's custom backburner instance.
|
|
176
|
-
*
|
|
177
|
-
* EmberData specific backburner instance
|
|
178
|
-
* @property _backburner
|
|
179
|
-
* @private
|
|
180
|
-
*/
|
|
181
|
-
declare _backburner: Backburner;
|
|
182
170
|
declare recordArrayManager: RecordArrayManager;
|
|
183
171
|
|
|
184
172
|
declare _notificationManager: NotificationManager;
|
|
@@ -230,10 +218,6 @@ class Store extends Service {
|
|
|
230
218
|
this._serializerCache = Object.create(null);
|
|
231
219
|
this._modelFactoryCache = Object.create(null);
|
|
232
220
|
|
|
233
|
-
// private
|
|
234
|
-
// TODO we should find a path to something simpler than backburner
|
|
235
|
-
this._backburner = edBackburner;
|
|
236
|
-
|
|
237
221
|
if (DEBUG) {
|
|
238
222
|
if (this.generateStackTracesForTrackedRequests === undefined) {
|
|
239
223
|
this.generateStackTracesForTrackedRequests = false;
|
|
@@ -281,6 +265,37 @@ class Store extends Service {
|
|
|
281
265
|
}
|
|
282
266
|
}
|
|
283
267
|
|
|
268
|
+
declare _cbs: { coalesce?: () => void; sync?: () => void; notify?: () => void } | null;
|
|
269
|
+
_run(cb: () => void) {
|
|
270
|
+
assert(`EmberData should never encounter a nested run`, !this._cbs);
|
|
271
|
+
const _cbs: { coalesce?: () => void; sync?: () => void; notify?: () => void } = (this._cbs = {});
|
|
272
|
+
cb();
|
|
273
|
+
if (_cbs.coalesce) {
|
|
274
|
+
_cbs.coalesce();
|
|
275
|
+
}
|
|
276
|
+
if (_cbs.sync) {
|
|
277
|
+
_cbs.sync();
|
|
278
|
+
}
|
|
279
|
+
if (_cbs.notify) {
|
|
280
|
+
_cbs.notify();
|
|
281
|
+
}
|
|
282
|
+
this._cbs = null;
|
|
283
|
+
}
|
|
284
|
+
_join(cb: () => void): void {
|
|
285
|
+
if (this._cbs) {
|
|
286
|
+
cb();
|
|
287
|
+
} else {
|
|
288
|
+
this._run(cb);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
_schedule(name: 'coalesce' | 'sync' | 'notify', cb: () => void): void {
|
|
293
|
+
assert(`EmberData expects to schedule only when there is an active run`, !!this._cbs);
|
|
294
|
+
assert(`EmberData expects only one flush per queue name, cannot schedule ${name}`, !this._cbs[name]);
|
|
295
|
+
|
|
296
|
+
this._cbs[name] = cb;
|
|
297
|
+
}
|
|
298
|
+
|
|
284
299
|
/**
|
|
285
300
|
* Retrieve the RequestStateService instance
|
|
286
301
|
* associated with this Store.
|
|
@@ -321,25 +336,23 @@ class Store extends Service {
|
|
|
321
336
|
): DSModel | RecordInstance {
|
|
322
337
|
if (HAS_MODEL_PACKAGE) {
|
|
323
338
|
let modelName = identifier.type;
|
|
324
|
-
let store = this;
|
|
325
339
|
|
|
326
340
|
let recordData = this._instanceCache.getRecordData(identifier);
|
|
341
|
+
// TODO deprecate allowing unknown args setting
|
|
327
342
|
let createOptions: any = {
|
|
328
|
-
// TODO deprecate allowing unknown args setting
|
|
329
343
|
_createProps: createRecordArgs,
|
|
330
344
|
// TODO @deprecate consider deprecating accessing record properties during init which the below is necessary for
|
|
331
|
-
_secretInit:
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
345
|
+
_secretInit: {
|
|
346
|
+
identifier,
|
|
347
|
+
recordData,
|
|
348
|
+
store: this,
|
|
349
|
+
cb: secretInit,
|
|
335
350
|
},
|
|
336
|
-
container: null, // necessary hack for setOwner?
|
|
337
351
|
};
|
|
338
352
|
|
|
339
353
|
// ensure that `getOwner(this)` works inside a model instance
|
|
340
354
|
setOwner(createOptions, getOwner(this));
|
|
341
|
-
|
|
342
|
-
return getModelFactory(this, this._modelFactoryCache, modelName).create(createOptions);
|
|
355
|
+
return getModelFactory(this, this._modelFactoryCache, modelName).class.create(createOptions);
|
|
343
356
|
}
|
|
344
357
|
assert(`You must implement the store's instantiateRecord hook for your custom model class.`);
|
|
345
358
|
}
|
|
@@ -394,15 +407,53 @@ class Store extends Service {
|
|
|
394
407
|
* for use when information about a resource's schema needs
|
|
395
408
|
* to be queried.
|
|
396
409
|
*
|
|
397
|
-
* This method can only be called
|
|
398
|
-
*
|
|
410
|
+
* This method can only be called more than once, but only one schema
|
|
411
|
+
* definition service may exist. Therefore if you wish to chain services
|
|
412
|
+
* you must lookup the existing service and close over it with the new
|
|
413
|
+
* service by calling `getSchemaDefinitionService` prior to registration.
|
|
414
|
+
*
|
|
415
|
+
* For Example:
|
|
416
|
+
*
|
|
417
|
+
* ```ts
|
|
418
|
+
* import Store from '@ember-data/store';
|
|
419
|
+
*
|
|
420
|
+
* class SchemaDelegator {
|
|
421
|
+
* constructor(schema) {
|
|
422
|
+
* this._schema = schema;
|
|
423
|
+
* }
|
|
424
|
+
*
|
|
425
|
+
* doesTypeExist(type: string): boolean {
|
|
426
|
+
* if (AbstractSchemas.has(type)) {
|
|
427
|
+
* return true;
|
|
428
|
+
* }
|
|
429
|
+
* return this._schema.doesTypeExist(type);
|
|
430
|
+
* }
|
|
431
|
+
*
|
|
432
|
+
* attributesDefinitionFor(identifier: RecordIdentifier | { type: string }): AttributesSchema {
|
|
433
|
+
* return this._schema.attributesDefinitionFor(identifier);
|
|
434
|
+
* }
|
|
435
|
+
*
|
|
436
|
+
* relationshipsDefinitionFor(identifier: RecordIdentifier | { type: string }): RelationshipsSchema {
|
|
437
|
+
* const schema = AbstractSchemas.get(identifier.type);
|
|
438
|
+
* return schema || this._schema.relationshipsDefinitionFor(identifier);
|
|
439
|
+
* }
|
|
440
|
+
* }
|
|
441
|
+
*
|
|
442
|
+
* export default class extends Store {
|
|
443
|
+
* constructor(...args) {
|
|
444
|
+
* super(...args);
|
|
445
|
+
*
|
|
446
|
+
* const schema = this.getSchemaDefinitionService();
|
|
447
|
+
* this.registerSchemaDefinitionService(new SchemaDelegator(schema));
|
|
448
|
+
* }
|
|
449
|
+
* }
|
|
450
|
+
* ```
|
|
399
451
|
*
|
|
400
452
|
* @method registerSchemaDefinitionService
|
|
401
453
|
* @param {SchemaDefinitionService} schema
|
|
402
454
|
* @public
|
|
403
455
|
*/
|
|
404
456
|
registerSchemaDefinitionService(schema: SchemaDefinitionService) {
|
|
405
|
-
assert(`Cannot register a schema definition service when one already exists`, !this._schemaDefinitionService);
|
|
406
457
|
this._schemaDefinitionService = schema;
|
|
407
458
|
}
|
|
408
459
|
|
|
@@ -508,8 +559,9 @@ class Store extends Service {
|
|
|
508
559
|
// of record-arrays via ember's run loop, not our own.
|
|
509
560
|
//
|
|
510
561
|
// to remove this, we would need to move to a new `async` API.
|
|
511
|
-
|
|
512
|
-
|
|
562
|
+
let record!: RecordInstance;
|
|
563
|
+
emberBackburner.join(() => {
|
|
564
|
+
this._join(() => {
|
|
513
565
|
let normalizedModelName = normalizeModelName(modelName);
|
|
514
566
|
let properties = { ...inputProperties };
|
|
515
567
|
|
|
@@ -551,11 +603,12 @@ class Store extends Service {
|
|
|
551
603
|
(recordData as NonSingletonRecordDataManager).managedVersion === '1'
|
|
552
604
|
);
|
|
553
605
|
const resultProps = recordData.clientDidCreate(identifier, createOptions);
|
|
554
|
-
this.recordArrayManager.
|
|
606
|
+
this.recordArrayManager.identifierAdded(identifier);
|
|
555
607
|
|
|
556
|
-
|
|
608
|
+
record = this._instanceCache.getRecord(identifier, resultProps);
|
|
557
609
|
});
|
|
558
610
|
});
|
|
611
|
+
return record;
|
|
559
612
|
}
|
|
560
613
|
|
|
561
614
|
/**
|
|
@@ -583,13 +636,15 @@ class Store extends Service {
|
|
|
583
636
|
const identifier = peekRecordIdentifier(record);
|
|
584
637
|
const recordData = identifier && this._instanceCache.peek({ identifier, bucket: 'recordData' });
|
|
585
638
|
assert(`expected a recordData instance to exist for the record`, recordData);
|
|
586
|
-
|
|
639
|
+
this._join(() => {
|
|
640
|
+
recordData.setIsDeleted(identifier, true);
|
|
587
641
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
642
|
+
if (recordData.isNew(identifier)) {
|
|
643
|
+
run(() => {
|
|
644
|
+
this._instanceCache.unloadRecord(identifier);
|
|
645
|
+
});
|
|
646
|
+
}
|
|
647
|
+
});
|
|
593
648
|
}
|
|
594
649
|
|
|
595
650
|
/**
|
|
@@ -612,7 +667,7 @@ class Store extends Service {
|
|
|
612
667
|
if (DEBUG) {
|
|
613
668
|
assertDestroyingStore(this, 'unloadRecord');
|
|
614
669
|
}
|
|
615
|
-
|
|
670
|
+
const identifier = peekRecordIdentifier(record);
|
|
616
671
|
if (identifier) {
|
|
617
672
|
this._instanceCache.unloadRecord(identifier);
|
|
618
673
|
}
|
|
@@ -1079,14 +1134,14 @@ class Store extends Service {
|
|
|
1079
1134
|
assertIdentifierHasId(identifier);
|
|
1080
1135
|
promise = this._fetchManager.scheduleFetch(identifier, options);
|
|
1081
1136
|
} else {
|
|
1082
|
-
let snapshot =
|
|
1137
|
+
let snapshot: Snapshot | null = null;
|
|
1083
1138
|
let adapter = this.adapterFor(identifier.type);
|
|
1084
1139
|
|
|
1085
1140
|
// Refetch the record if the adapter thinks the record is stale
|
|
1086
1141
|
if (
|
|
1087
1142
|
typeof options.reload === 'undefined' &&
|
|
1088
1143
|
adapter.shouldReloadRecord &&
|
|
1089
|
-
adapter.shouldReloadRecord(this, snapshot)
|
|
1144
|
+
adapter.shouldReloadRecord(this, (snapshot = this._instanceCache.createSnapshot(identifier, options)))
|
|
1090
1145
|
) {
|
|
1091
1146
|
assertIdentifierHasId(identifier);
|
|
1092
1147
|
promise = this._fetchManager.scheduleFetch(identifier, options);
|
|
@@ -1096,7 +1151,10 @@ class Store extends Service {
|
|
|
1096
1151
|
options.backgroundReload !== false &&
|
|
1097
1152
|
(options.backgroundReload ||
|
|
1098
1153
|
!adapter.shouldBackgroundReloadRecord ||
|
|
1099
|
-
adapter.shouldBackgroundReloadRecord(
|
|
1154
|
+
adapter.shouldBackgroundReloadRecord(
|
|
1155
|
+
this,
|
|
1156
|
+
(snapshot = snapshot || this._instanceCache.createSnapshot(identifier, options))
|
|
1157
|
+
))
|
|
1100
1158
|
) {
|
|
1101
1159
|
assertIdentifierHasId(identifier);
|
|
1102
1160
|
this._fetchManager.scheduleFetch(identifier, options);
|
|
@@ -1107,7 +1165,11 @@ class Store extends Service {
|
|
|
1107
1165
|
}
|
|
1108
1166
|
}
|
|
1109
1167
|
|
|
1110
|
-
|
|
1168
|
+
if (DEPRECATE_PROMISE_PROXIES) {
|
|
1169
|
+
return promiseRecord(this, promise);
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
return promise.then((identifier: StableRecordIdentifier) => this.peekRecord(identifier));
|
|
1111
1173
|
}
|
|
1112
1174
|
|
|
1113
1175
|
/**
|
|
@@ -1338,8 +1400,8 @@ class Store extends Service {
|
|
|
1338
1400
|
decoded: "/api/v1/person?ids[]=1&ids[]=2&ids[]=3"
|
|
1339
1401
|
```
|
|
1340
1402
|
|
|
1341
|
-
This method returns a promise, which is resolved with
|
|
1342
|
-
[`
|
|
1403
|
+
This method returns a promise, which is resolved with a
|
|
1404
|
+
[`Collection`](/ember-data/release/classes/Collection)
|
|
1343
1405
|
once the server returns.
|
|
1344
1406
|
|
|
1345
1407
|
@since 1.13.0
|
|
@@ -1350,7 +1412,7 @@ class Store extends Service {
|
|
|
1350
1412
|
@param {Object} options optional, may include `adapterOptions` hash which will be passed to adapter.query
|
|
1351
1413
|
@return {Promise} promise
|
|
1352
1414
|
*/
|
|
1353
|
-
query(modelName: string, query, options): PromiseArray<RecordInstance,
|
|
1415
|
+
query(modelName: string, query, options): PromiseArray<RecordInstance, Collection> | Promise<Collection> {
|
|
1354
1416
|
if (DEBUG) {
|
|
1355
1417
|
assertDestroyingStore(this, 'query');
|
|
1356
1418
|
}
|
|
@@ -1384,9 +1446,12 @@ class Store extends Service {
|
|
|
1384
1446
|
query,
|
|
1385
1447
|
recordArray,
|
|
1386
1448
|
adapterOptionsWrapper
|
|
1387
|
-
) as unknown as Promise<
|
|
1449
|
+
) as unknown as Promise<Collection>;
|
|
1388
1450
|
|
|
1389
|
-
|
|
1451
|
+
if (DEPRECATE_PROMISE_PROXIES) {
|
|
1452
|
+
return promiseArray(queryPromise);
|
|
1453
|
+
}
|
|
1454
|
+
return queryPromise;
|
|
1390
1455
|
}
|
|
1391
1456
|
|
|
1392
1457
|
/**
|
|
@@ -1487,7 +1552,11 @@ class Store extends Service {
|
|
|
1487
1552
|
@param {Object} options optional, may include `adapterOptions` hash which will be passed to adapter.queryRecord
|
|
1488
1553
|
@return {Promise} promise which resolves with the found record or `null`
|
|
1489
1554
|
*/
|
|
1490
|
-
queryRecord(
|
|
1555
|
+
queryRecord(
|
|
1556
|
+
modelName: string,
|
|
1557
|
+
query,
|
|
1558
|
+
options?
|
|
1559
|
+
): PromiseObject<RecordInstance | null> | Promise<RecordInstance | null> {
|
|
1491
1560
|
if (DEBUG) {
|
|
1492
1561
|
assertDestroyingStore(this, 'queryRecord');
|
|
1493
1562
|
}
|
|
@@ -1520,7 +1589,10 @@ class Store extends Service {
|
|
|
1520
1589
|
adapterOptionsWrapper
|
|
1521
1590
|
) as Promise<StableRecordIdentifier | null>;
|
|
1522
1591
|
|
|
1523
|
-
|
|
1592
|
+
if (DEPRECATE_PROMISE_PROXIES) {
|
|
1593
|
+
return promiseObject(promise.then((identifier) => identifier && this.peekRecord(identifier)));
|
|
1594
|
+
}
|
|
1595
|
+
return promise.then((identifier) => identifier && this.peekRecord(identifier));
|
|
1524
1596
|
}
|
|
1525
1597
|
|
|
1526
1598
|
/**
|
|
@@ -1714,7 +1786,7 @@ class Store extends Service {
|
|
|
1714
1786
|
findAll(
|
|
1715
1787
|
modelName: string,
|
|
1716
1788
|
options: { reload?: boolean; backgroundReload?: boolean } = {}
|
|
1717
|
-
): PromiseArray<RecordInstance,
|
|
1789
|
+
): PromiseArray<RecordInstance, IdentifierArray> {
|
|
1718
1790
|
if (DEBUG) {
|
|
1719
1791
|
assertDestroyingStore(this, 'findAll');
|
|
1720
1792
|
}
|
|
@@ -1740,7 +1812,7 @@ class Store extends Service {
|
|
|
1740
1812
|
array.isUpdating = true;
|
|
1741
1813
|
fetch = _findAll(adapter, this, normalizedModelName, options);
|
|
1742
1814
|
} else {
|
|
1743
|
-
let snapshotArray = array
|
|
1815
|
+
let snapshotArray = new SnapshotRecordArray(this, array, options);
|
|
1744
1816
|
|
|
1745
1817
|
if (options.reload !== false) {
|
|
1746
1818
|
if (
|
|
@@ -1748,7 +1820,7 @@ class Store extends Service {
|
|
|
1748
1820
|
(!adapter.shouldReloadAll && snapshotArray.length === 0)
|
|
1749
1821
|
) {
|
|
1750
1822
|
array.isUpdating = true;
|
|
1751
|
-
fetch = _findAll(adapter, this, modelName, options);
|
|
1823
|
+
fetch = _findAll(adapter, this, modelName, options, snapshotArray);
|
|
1752
1824
|
}
|
|
1753
1825
|
}
|
|
1754
1826
|
|
|
@@ -1761,14 +1833,17 @@ class Store extends Service {
|
|
|
1761
1833
|
adapter.shouldBackgroundReloadAll(this, snapshotArray)
|
|
1762
1834
|
) {
|
|
1763
1835
|
array.isUpdating = true;
|
|
1764
|
-
_findAll(adapter, this, modelName, options);
|
|
1836
|
+
_findAll(adapter, this, modelName, options, snapshotArray);
|
|
1765
1837
|
}
|
|
1766
1838
|
|
|
1767
1839
|
fetch = resolve(array);
|
|
1768
1840
|
}
|
|
1769
1841
|
}
|
|
1770
1842
|
|
|
1771
|
-
|
|
1843
|
+
if (DEPRECATE_PROMISE_PROXIES) {
|
|
1844
|
+
return promiseArray(fetch);
|
|
1845
|
+
}
|
|
1846
|
+
return fetch;
|
|
1772
1847
|
}
|
|
1773
1848
|
|
|
1774
1849
|
/**
|
|
@@ -1796,7 +1871,7 @@ class Store extends Service {
|
|
|
1796
1871
|
@param {String} modelName
|
|
1797
1872
|
@return {RecordArray}
|
|
1798
1873
|
*/
|
|
1799
|
-
peekAll(modelName) {
|
|
1874
|
+
peekAll(modelName: string): IdentifierArray {
|
|
1800
1875
|
if (DEBUG) {
|
|
1801
1876
|
assertDestroyingStore(this, 'peekAll');
|
|
1802
1877
|
}
|
|
@@ -1805,8 +1880,9 @@ class Store extends Service {
|
|
|
1805
1880
|
`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${modelName}`,
|
|
1806
1881
|
typeof modelName === 'string'
|
|
1807
1882
|
);
|
|
1808
|
-
|
|
1809
|
-
|
|
1883
|
+
|
|
1884
|
+
let type = normalizeModelName(modelName);
|
|
1885
|
+
return this.recordArrayManager.liveArrayFor(type);
|
|
1810
1886
|
}
|
|
1811
1887
|
|
|
1812
1888
|
/**
|
|
@@ -1833,24 +1909,29 @@ class Store extends Service {
|
|
|
1833
1909
|
!modelName || typeof modelName === 'string'
|
|
1834
1910
|
);
|
|
1835
1911
|
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
graph
|
|
1912
|
+
this._join(() => {
|
|
1913
|
+
if (modelName === undefined) {
|
|
1914
|
+
// destroy the graph before unloadAll
|
|
1915
|
+
// since then we avoid churning relationships
|
|
1916
|
+
// during unload
|
|
1917
|
+
if (HAS_RECORD_DATA_PACKAGE) {
|
|
1918
|
+
const peekGraph = (
|
|
1919
|
+
importSync('@ember-data/record-data/-private') as typeof import('@ember-data/record-data/-private')
|
|
1920
|
+
).peekGraph;
|
|
1921
|
+
let graph = peekGraph(this);
|
|
1922
|
+
if (graph) {
|
|
1923
|
+
graph.identifiers.clear();
|
|
1924
|
+
}
|
|
1847
1925
|
}
|
|
1926
|
+
this._notificationManager.destroy();
|
|
1927
|
+
|
|
1928
|
+
this.recordArrayManager.clear();
|
|
1929
|
+
this._instanceCache.clear();
|
|
1930
|
+
} else {
|
|
1931
|
+
let normalizedModelName = normalizeModelName(modelName);
|
|
1932
|
+
this._instanceCache.clear(normalizedModelName);
|
|
1848
1933
|
}
|
|
1849
|
-
|
|
1850
|
-
} else {
|
|
1851
|
-
let normalizedModelName = normalizeModelName(modelName);
|
|
1852
|
-
this._instanceCache.clear(normalizedModelName);
|
|
1853
|
-
}
|
|
1934
|
+
});
|
|
1854
1935
|
}
|
|
1855
1936
|
|
|
1856
1937
|
/**
|
|
@@ -2038,7 +2119,8 @@ class Store extends Service {
|
|
|
2038
2119
|
if (DEBUG) {
|
|
2039
2120
|
assertDestroyingStore(this, '_push');
|
|
2040
2121
|
}
|
|
2041
|
-
let
|
|
2122
|
+
let ret;
|
|
2123
|
+
this._join(() => {
|
|
2042
2124
|
let included = jsonApiDoc.included;
|
|
2043
2125
|
let i, length;
|
|
2044
2126
|
|
|
@@ -2055,11 +2137,13 @@ class Store extends Service {
|
|
|
2055
2137
|
for (i = 0; i < length; i++) {
|
|
2056
2138
|
identifiers[i] = this._instanceCache.loadData(jsonApiDoc.data[i]);
|
|
2057
2139
|
}
|
|
2058
|
-
|
|
2140
|
+
ret = identifiers;
|
|
2141
|
+
return;
|
|
2059
2142
|
}
|
|
2060
2143
|
|
|
2061
2144
|
if (jsonApiDoc.data === null) {
|
|
2062
|
-
|
|
2145
|
+
ret = null;
|
|
2146
|
+
return;
|
|
2063
2147
|
}
|
|
2064
2148
|
|
|
2065
2149
|
assert(
|
|
@@ -2069,11 +2153,11 @@ class Store extends Service {
|
|
|
2069
2153
|
typeof jsonApiDoc.data === 'object'
|
|
2070
2154
|
);
|
|
2071
2155
|
|
|
2072
|
-
|
|
2156
|
+
ret = this._instanceCache.loadData(jsonApiDoc.data);
|
|
2157
|
+
return;
|
|
2073
2158
|
});
|
|
2074
2159
|
|
|
2075
|
-
|
|
2076
|
-
return identifiers;
|
|
2160
|
+
return ret;
|
|
2077
2161
|
}
|
|
2078
2162
|
|
|
2079
2163
|
/**
|
|
@@ -2228,7 +2312,7 @@ class Store extends Service {
|
|
|
2228
2312
|
have an outer run loop available still from the first
|
|
2229
2313
|
call to `store._push`;
|
|
2230
2314
|
*/
|
|
2231
|
-
this.
|
|
2315
|
+
this._join(() => {
|
|
2232
2316
|
if (DEBUG) {
|
|
2233
2317
|
assertDestroyingStore(this, 'saveRecord');
|
|
2234
2318
|
}
|
|
@@ -2250,7 +2334,10 @@ class Store extends Service {
|
|
|
2250
2334
|
//We first make sure the primary data has been updated
|
|
2251
2335
|
const recordData = this._instanceCache.getRecordData(actualIdentifier);
|
|
2252
2336
|
recordData.didCommit(identifier, data);
|
|
2253
|
-
|
|
2337
|
+
|
|
2338
|
+
if (operation === 'deleteRecord') {
|
|
2339
|
+
this.recordArrayManager.identifierRemoved(actualIdentifier);
|
|
2340
|
+
}
|
|
2254
2341
|
|
|
2255
2342
|
if (payload && payload.included) {
|
|
2256
2343
|
this._push({ data: null, included: payload.included });
|
|
@@ -2315,17 +2402,11 @@ class Store extends Service {
|
|
|
2315
2402
|
storeWrapper = arguments[3];
|
|
2316
2403
|
}
|
|
2317
2404
|
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
this.__private_singleton_recordData
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
).createCache(identifier);
|
|
2324
|
-
return this.__private_singleton_recordData;
|
|
2325
|
-
}
|
|
2326
|
-
|
|
2327
|
-
// @ts-expect-error
|
|
2328
|
-
return new _RecordData(identifier, storeWrapper);
|
|
2405
|
+
this.__private_singleton_recordData = this.__private_singleton_recordData || new _RecordData(storeWrapper);
|
|
2406
|
+
(
|
|
2407
|
+
this.__private_singleton_recordData as RecordData & { createCache(identifier: StableRecordIdentifier): void }
|
|
2408
|
+
).createCache(identifier);
|
|
2409
|
+
return this.__private_singleton_recordData;
|
|
2329
2410
|
}
|
|
2330
2411
|
|
|
2331
2412
|
assert(`Expected store.createRecordDataFor to be implemented but it wasn't`);
|
|
@@ -2532,16 +2613,6 @@ class Store extends Service {
|
|
|
2532
2613
|
this.recordArrayManager.destroy();
|
|
2533
2614
|
this.identifierCache.destroy();
|
|
2534
2615
|
|
|
2535
|
-
if (HAS_RECORD_DATA_PACKAGE) {
|
|
2536
|
-
const peekGraph = (
|
|
2537
|
-
importSync('@ember-data/record-data/-private') as typeof import('@ember-data/record-data/-private')
|
|
2538
|
-
).peekGraph;
|
|
2539
|
-
let graph = peekGraph(this);
|
|
2540
|
-
if (graph) {
|
|
2541
|
-
graph.willDestroy();
|
|
2542
|
-
}
|
|
2543
|
-
}
|
|
2544
|
-
|
|
2545
2616
|
this.unloadAll();
|
|
2546
2617
|
|
|
2547
2618
|
if (DEBUG) {
|
|
@@ -2758,12 +2829,25 @@ function extractIdentifierFromRecord(
|
|
|
2758
2829
|
}
|
|
2759
2830
|
const extract = isForV1 ? recordDataFor : recordIdentifierFor;
|
|
2760
2831
|
|
|
2761
|
-
if (isPromiseRecord(recordOrPromiseRecord)) {
|
|
2832
|
+
if (DEPRECATE_PROMISE_PROXIES && isPromiseRecord(recordOrPromiseRecord)) {
|
|
2762
2833
|
let content = recordOrPromiseRecord.content;
|
|
2763
2834
|
assert(
|
|
2764
2835
|
'You passed in a promise that did not originate from an EmberData relationship. You can only pass promises that come from a belongsTo or hasMany relationship to the get call.',
|
|
2765
2836
|
content !== undefined
|
|
2766
2837
|
);
|
|
2838
|
+
deprecate(
|
|
2839
|
+
`You passed in a PromiseProxy to a Relationship API that now expects a resolved value. await the value before setting it.`,
|
|
2840
|
+
false,
|
|
2841
|
+
{
|
|
2842
|
+
id: 'ember-data:deprecate-promise-proxies',
|
|
2843
|
+
until: '5.0',
|
|
2844
|
+
since: {
|
|
2845
|
+
enabled: '4.8',
|
|
2846
|
+
available: '4.8',
|
|
2847
|
+
},
|
|
2848
|
+
for: 'ember-data',
|
|
2849
|
+
}
|
|
2850
|
+
);
|
|
2767
2851
|
return content ? extract(content) : null;
|
|
2768
2852
|
}
|
|
2769
2853
|
|
|
@@ -2773,3 +2857,14 @@ function extractIdentifierFromRecord(
|
|
|
2773
2857
|
function isPromiseRecord(record: PromiseProxyRecord | RecordInstance): record is PromiseProxyRecord {
|
|
2774
2858
|
return !!record.then;
|
|
2775
2859
|
}
|
|
2860
|
+
|
|
2861
|
+
function secretInit(
|
|
2862
|
+
record: RecordInstance,
|
|
2863
|
+
recordData: RecordData,
|
|
2864
|
+
identifier: StableRecordIdentifier,
|
|
2865
|
+
store: Store
|
|
2866
|
+
): void {
|
|
2867
|
+
setRecordIdentifier(record, identifier);
|
|
2868
|
+
StoreMap.set(record, store);
|
|
2869
|
+
setRecordDataFor(record, recordData);
|
|
2870
|
+
}
|
|
@@ -7,10 +7,9 @@ import type Store from '../store-service';
|
|
|
7
7
|
|
|
8
8
|
export default function promiseRecord(
|
|
9
9
|
store: Store,
|
|
10
|
-
promise: Promise<StableRecordIdentifier
|
|
11
|
-
label?: string
|
|
10
|
+
promise: Promise<StableRecordIdentifier>
|
|
12
11
|
): PromiseObject<RecordInstance> {
|
|
13
12
|
let toReturn = promise.then((identifier: StableRecordIdentifier) => store.peekRecord(identifier)!);
|
|
14
13
|
|
|
15
|
-
return promiseObject(toReturn
|
|
14
|
+
return promiseObject(toReturn);
|
|
16
15
|
}
|