@ember-data/store 5.4.0-alpha.137 → 5.4.0-alpha.139
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/dist/-private.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{handler-BQ09uu8f.js → many-array-DJ3xLLia.js} +698 -120
- package/dist/many-array-DJ3xLLia.js.map +1 -0
- package/package.json +11 -11
- package/unstable-preview-types/-private/managers/cache-manager.d.ts +22 -0
- package/unstable-preview-types/-private/managers/cache-manager.d.ts.map +1 -1
- package/unstable-preview-types/-private/managers/notification-manager.d.ts.map +1 -1
- package/unstable-preview-types/-private/managers/record-array-manager.d.ts +2 -0
- package/unstable-preview-types/-private/managers/record-array-manager.d.ts.map +1 -1
- package/unstable-preview-types/-private/record-arrays/identifier-array.d.ts +11 -1
- package/unstable-preview-types/-private/record-arrays/identifier-array.d.ts.map +1 -1
- package/unstable-preview-types/-private/record-arrays/many-array.d.ts +199 -0
- package/unstable-preview-types/-private/record-arrays/many-array.d.ts.map +1 -0
- package/unstable-preview-types/-private/store-service.d.ts +2 -3
- package/unstable-preview-types/-private/store-service.d.ts.map +1 -1
- package/unstable-preview-types/-private.d.ts +1 -0
- package/unstable-preview-types/-private.d.ts.map +1 -1
- package/unstable-preview-types/index.d.ts +1 -0
- package/dist/handler-BQ09uu8f.js.map +0 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { deprecate, warn } from '@ember/debug';
|
|
2
2
|
import { macroCondition, getGlobalConfig, dependencySatisfies, importSync } from '@embroider/macros';
|
|
3
|
+
import { setLogging, getRuntimeConfig } from '@warp-drive/build-config/runtime';
|
|
3
4
|
import { EnableHydration, SkipCache } from '@warp-drive/core-types/request';
|
|
4
5
|
import { getOrSetGlobal, setTransient, peekTransient } from '@warp-drive/core-types/-private';
|
|
6
|
+
import { _backburner } from '@ember/runloop';
|
|
7
|
+
import { defineSignal, createSignal, subscribe, createArrayTags, addToTransaction, addTransactionCB } from '@ember-data/tracking/-private';
|
|
5
8
|
import { CACHE_OWNER, DEBUG_STALE_CACHE_OWNER, DEBUG_CLIENT_ORIGINATED, DEBUG_IDENTIFIER_BUCKET } from '@warp-drive/core-types/identifier';
|
|
6
9
|
import { dasherize } from '@ember-data/request-utils/string';
|
|
7
|
-
import { defineSignal, createSignal, subscribe, createArrayTags, addToTransaction, addTransactionCB } from '@ember-data/tracking/-private';
|
|
8
|
-
import { _backburner } from '@ember/runloop';
|
|
9
10
|
import { compat } from '@ember-data/tracking';
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -309,9 +310,11 @@ class IdentifierCache {
|
|
|
309
310
|
*/
|
|
310
311
|
|
|
311
312
|
_getRecordIdentifier(resource, shouldGenerate) {
|
|
312
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
313
|
-
|
|
314
|
-
|
|
313
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
314
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
315
|
+
// eslint-disable-next-line no-console
|
|
316
|
+
console.groupCollapsed(`Identifiers: ${shouldGenerate ? 'Generating' : 'Peeking'} Identifier`, resource);
|
|
317
|
+
}
|
|
315
318
|
}
|
|
316
319
|
// short circuit if we're already the stable version
|
|
317
320
|
if (isStableIdentifier(resource)) {
|
|
@@ -321,33 +324,41 @@ class IdentifierCache {
|
|
|
321
324
|
throw new Error(`The supplied identifier ${JSON.stringify(resource)} does not belong to this store instance`);
|
|
322
325
|
}
|
|
323
326
|
}
|
|
324
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
327
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
328
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
329
|
+
// eslint-disable-next-line no-console
|
|
330
|
+
console.log(`Identifiers: cache HIT - Stable ${resource.lid}`);
|
|
331
|
+
// eslint-disable-next-line no-console
|
|
332
|
+
console.groupEnd();
|
|
333
|
+
}
|
|
329
334
|
}
|
|
330
335
|
return resource;
|
|
331
336
|
}
|
|
332
337
|
|
|
333
338
|
// the resource is unknown, ask the application to identify this data for us
|
|
334
339
|
const lid = this._generate(resource, 'record');
|
|
335
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
336
|
-
|
|
337
|
-
|
|
340
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
341
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
342
|
+
// eslint-disable-next-line no-console
|
|
343
|
+
console.log(`Identifiers: ${lid ? 'no ' : ''}lid ${lid ? lid + ' ' : ''}determined for resource`, resource);
|
|
344
|
+
}
|
|
338
345
|
}
|
|
339
346
|
let identifier = /*#__NOINLINE__*/getIdentifierFromLid(this._cache, lid, resource);
|
|
340
347
|
if (identifier !== null) {
|
|
341
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
342
|
-
|
|
343
|
-
|
|
348
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
349
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
350
|
+
// eslint-disable-next-line no-console
|
|
351
|
+
console.groupEnd();
|
|
352
|
+
}
|
|
344
353
|
}
|
|
345
354
|
return identifier;
|
|
346
355
|
}
|
|
347
356
|
if (shouldGenerate === 0) {
|
|
348
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
349
|
-
|
|
350
|
-
|
|
357
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
358
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
359
|
+
// eslint-disable-next-line no-console
|
|
360
|
+
console.groupEnd();
|
|
361
|
+
}
|
|
351
362
|
}
|
|
352
363
|
return;
|
|
353
364
|
}
|
|
@@ -365,9 +376,11 @@ class IdentifierCache {
|
|
|
365
376
|
identifier = /*#__NOINLINE__*/makeStableRecordIdentifier(keyInfo, 'record', false);
|
|
366
377
|
}
|
|
367
378
|
addResourceToCache(this._cache, identifier);
|
|
368
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
369
|
-
|
|
370
|
-
|
|
379
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
380
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
381
|
+
// eslint-disable-next-line no-console
|
|
382
|
+
console.groupEnd();
|
|
383
|
+
}
|
|
371
384
|
}
|
|
372
385
|
return identifier;
|
|
373
386
|
}
|
|
@@ -461,9 +474,11 @@ class IdentifierCache {
|
|
|
461
474
|
|
|
462
475
|
/*#__NOINLINE__*/
|
|
463
476
|
addResourceToCache(this._cache, identifier);
|
|
464
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
465
|
-
|
|
466
|
-
|
|
477
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
478
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
479
|
+
// eslint-disable-next-line no-console
|
|
480
|
+
console.log(`Identifiers: created identifier ${String(identifier)} for newly generated resource`, data);
|
|
481
|
+
}
|
|
467
482
|
}
|
|
468
483
|
return identifier;
|
|
469
484
|
}
|
|
@@ -510,9 +525,11 @@ class IdentifierCache {
|
|
|
510
525
|
if (hadLid) {
|
|
511
526
|
data.lid = identifier.lid;
|
|
512
527
|
}
|
|
513
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
514
|
-
|
|
515
|
-
|
|
528
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
529
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
530
|
+
// eslint-disable-next-line no-console
|
|
531
|
+
console.log(`Identifiers: merged identifiers ${generatedIdentifier.lid} and ${existingIdentifier.lid} for resource into ${identifier.lid}`, data);
|
|
532
|
+
}
|
|
516
533
|
}
|
|
517
534
|
}
|
|
518
535
|
const id = identifier.id;
|
|
@@ -522,9 +539,11 @@ class IdentifierCache {
|
|
|
522
539
|
|
|
523
540
|
// add to our own secondary lookup table
|
|
524
541
|
if (id !== newId && newId !== null) {
|
|
525
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
526
|
-
|
|
527
|
-
|
|
542
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
543
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
544
|
+
// eslint-disable-next-line no-console
|
|
545
|
+
console.log(`Identifiers: updated id for identifier ${identifier.lid} from '${String(id)}' to '${String(newId)}' for resource`, data);
|
|
546
|
+
}
|
|
528
547
|
}
|
|
529
548
|
const typeSet = this._cache.resourcesByType[identifier.type];
|
|
530
549
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
@@ -536,9 +555,11 @@ class IdentifierCache {
|
|
|
536
555
|
if (id !== null) {
|
|
537
556
|
typeSet.id.delete(id);
|
|
538
557
|
}
|
|
539
|
-
} else if (macroCondition(getGlobalConfig().WarpDrive.
|
|
540
|
-
|
|
541
|
-
|
|
558
|
+
} else if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
559
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
560
|
+
// eslint-disable-next-line no-console
|
|
561
|
+
console.log(`Identifiers: updated identifier ${identifier.lid} resource`, data);
|
|
562
|
+
}
|
|
542
563
|
}
|
|
543
564
|
return identifier;
|
|
544
565
|
}
|
|
@@ -621,9 +642,11 @@ class IdentifierCache {
|
|
|
621
642
|
}
|
|
622
643
|
identifier[CACHE_OWNER] = undefined;
|
|
623
644
|
this._forget(identifier, 'record');
|
|
624
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
625
|
-
|
|
626
|
-
|
|
645
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
646
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
647
|
+
// eslint-disable-next-line no-console
|
|
648
|
+
console.log(`Identifiers: released identifier ${identifierObject.lid}`);
|
|
649
|
+
}
|
|
627
650
|
}
|
|
628
651
|
}
|
|
629
652
|
destroy() {
|
|
@@ -771,9 +794,11 @@ function detectMerge(cache, keyInfo, identifier, data) {
|
|
|
771
794
|
}
|
|
772
795
|
function getIdentifierFromLid(cache, lid, resource) {
|
|
773
796
|
const identifier = cache.resources.get(lid);
|
|
774
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
775
|
-
|
|
776
|
-
|
|
797
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
798
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
799
|
+
// eslint-disable-next-line no-console
|
|
800
|
+
console.log(`Identifiers: cache ${identifier ? 'HIT' : 'MISS'} - Non-Stable ${lid}`, resource);
|
|
801
|
+
}
|
|
777
802
|
}
|
|
778
803
|
return identifier || null;
|
|
779
804
|
}
|
|
@@ -1329,14 +1354,16 @@ class InstanceCache {
|
|
|
1329
1354
|
setCacheFor(record, cache);
|
|
1330
1355
|
StoreMap.set(record, this.store);
|
|
1331
1356
|
this.__instances.record.set(identifier, record);
|
|
1332
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1357
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1358
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1359
|
+
logGroup('reactive-ui', '', identifier.type, identifier.lid, 'created', '');
|
|
1360
|
+
// eslint-disable-next-line no-console
|
|
1361
|
+
console.log({
|
|
1362
|
+
properties
|
|
1363
|
+
});
|
|
1364
|
+
// eslint-disable-next-line no-console
|
|
1365
|
+
console.groupEnd();
|
|
1366
|
+
}
|
|
1340
1367
|
}
|
|
1341
1368
|
}
|
|
1342
1369
|
return record;
|
|
@@ -1382,8 +1409,10 @@ class InstanceCache {
|
|
|
1382
1409
|
this.store.identifierCache.forgetRecordIdentifier(identifier);
|
|
1383
1410
|
removeRecordDataFor(identifier);
|
|
1384
1411
|
this.store._requestCache._clearEntries(identifier);
|
|
1385
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1386
|
-
|
|
1412
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1413
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1414
|
+
log('reactive-ui', '', identifier.type, identifier.lid, 'disconnected', '');
|
|
1415
|
+
}
|
|
1387
1416
|
}
|
|
1388
1417
|
}
|
|
1389
1418
|
unloadRecord(identifier) {
|
|
@@ -1399,9 +1428,11 @@ class InstanceCache {
|
|
|
1399
1428
|
})() : {};
|
|
1400
1429
|
}
|
|
1401
1430
|
}
|
|
1402
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1403
|
-
|
|
1404
|
-
|
|
1431
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1432
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1433
|
+
// eslint-disable-next-line no-console
|
|
1434
|
+
console.groupCollapsed(`InstanceCache: unloading record for ${String(identifier)}`);
|
|
1435
|
+
}
|
|
1405
1436
|
}
|
|
1406
1437
|
|
|
1407
1438
|
// TODO is this join still necessary?
|
|
@@ -1414,27 +1445,33 @@ class InstanceCache {
|
|
|
1414
1445
|
StoreMap.delete(record);
|
|
1415
1446
|
RecordCache.delete(record);
|
|
1416
1447
|
removeRecordDataFor(record);
|
|
1417
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1418
|
-
|
|
1419
|
-
|
|
1448
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1449
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1450
|
+
// eslint-disable-next-line no-console
|
|
1451
|
+
console.log(`InstanceCache: destroyed record for ${String(identifier)}`);
|
|
1452
|
+
}
|
|
1420
1453
|
}
|
|
1421
1454
|
}
|
|
1422
1455
|
if (cache) {
|
|
1423
1456
|
cache.unloadRecord(identifier);
|
|
1424
1457
|
removeRecordDataFor(identifier);
|
|
1425
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1426
|
-
|
|
1427
|
-
|
|
1458
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1459
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1460
|
+
// eslint-disable-next-line no-console
|
|
1461
|
+
console.log(`InstanceCache: destroyed cache for ${String(identifier)}`);
|
|
1462
|
+
}
|
|
1428
1463
|
}
|
|
1429
1464
|
} else {
|
|
1430
1465
|
this.disconnect(identifier);
|
|
1431
1466
|
}
|
|
1432
1467
|
this.store._requestCache._clearEntries(identifier);
|
|
1433
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1468
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1469
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1470
|
+
// eslint-disable-next-line no-console
|
|
1471
|
+
console.log(`InstanceCache: unloaded RecordData for ${String(identifier)}`);
|
|
1472
|
+
// eslint-disable-next-line no-console
|
|
1473
|
+
console.groupEnd();
|
|
1474
|
+
}
|
|
1438
1475
|
}
|
|
1439
1476
|
});
|
|
1440
1477
|
}
|
|
@@ -1489,9 +1526,11 @@ class InstanceCache {
|
|
|
1489
1526
|
warn(`Your ${type} record was saved to the server, but the response does not have an id.`, !(oldId !== null && id === null));
|
|
1490
1527
|
return;
|
|
1491
1528
|
}
|
|
1492
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1493
|
-
|
|
1494
|
-
|
|
1529
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1530
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1531
|
+
// eslint-disable-next-line no-console
|
|
1532
|
+
console.log(`InstanceCache: updating id to '${id}' for record ${String(identifier)}`);
|
|
1533
|
+
}
|
|
1495
1534
|
}
|
|
1496
1535
|
const existingIdentifier = this.store.identifierCache.peekRecordIdentifier({
|
|
1497
1536
|
type,
|
|
@@ -1808,7 +1847,9 @@ class CacheManager {
|
|
|
1808
1847
|
peek(identifier) {
|
|
1809
1848
|
return this.#cache.peek(identifier);
|
|
1810
1849
|
}
|
|
1811
|
-
|
|
1850
|
+
peekRemoteState(identifier) {
|
|
1851
|
+
return this.#cache.peekRemoteState(identifier);
|
|
1852
|
+
}
|
|
1812
1853
|
/**
|
|
1813
1854
|
* Peek the Cache for the existing request data associated with
|
|
1814
1855
|
* a cacheable request
|
|
@@ -2031,6 +2072,19 @@ class CacheManager {
|
|
|
2031
2072
|
return this.#cache.getAttr(identifier, propertyName);
|
|
2032
2073
|
}
|
|
2033
2074
|
|
|
2075
|
+
/**
|
|
2076
|
+
* Retrieve the remote state for an attribute from the cache
|
|
2077
|
+
*
|
|
2078
|
+
* @method getRemoteAttr
|
|
2079
|
+
* @public
|
|
2080
|
+
* @param identifier
|
|
2081
|
+
* @param propertyName
|
|
2082
|
+
* @return {unknown}
|
|
2083
|
+
*/
|
|
2084
|
+
getRemoteAttr(identifier, propertyName) {
|
|
2085
|
+
return this.#cache.getRemoteAttr(identifier, propertyName);
|
|
2086
|
+
}
|
|
2087
|
+
|
|
2034
2088
|
/**
|
|
2035
2089
|
* Mutate the data for an attribute in the cache
|
|
2036
2090
|
*
|
|
@@ -2155,6 +2209,19 @@ class CacheManager {
|
|
|
2155
2209
|
return this.#cache.getRelationship(identifier, propertyName);
|
|
2156
2210
|
}
|
|
2157
2211
|
|
|
2212
|
+
/**
|
|
2213
|
+
* Query the cache for the remote state of a relationship property
|
|
2214
|
+
*
|
|
2215
|
+
* @method getRelationship
|
|
2216
|
+
* @public
|
|
2217
|
+
* @param identifier
|
|
2218
|
+
* @param propertyName
|
|
2219
|
+
* @return resource relationship object
|
|
2220
|
+
*/
|
|
2221
|
+
getRemoteRelationship(identifier, propertyName) {
|
|
2222
|
+
return this.#cache.getRemoteRelationship(identifier, propertyName);
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2158
2225
|
// Resource State
|
|
2159
2226
|
// ===============
|
|
2160
2227
|
|
|
@@ -2251,17 +2318,16 @@ function runLoopIsFlushing() {
|
|
|
2251
2318
|
function count(label) {
|
|
2252
2319
|
// @ts-expect-error
|
|
2253
2320
|
// eslint-disable-next-line
|
|
2254
|
-
globalThis.
|
|
2255
|
-
// @ts-expect-error
|
|
2256
|
-
// eslint-disable-next-line
|
|
2257
|
-
globalThis.counts[label] = (globalThis.counts[label] || 0) + 1;
|
|
2321
|
+
globalThis.__WarpDriveMetricCountData[label] = (globalThis.__WarpDriveMetricCountData[label] || 0) + 1;
|
|
2258
2322
|
}
|
|
2259
2323
|
function _unsubscribe(tokens, token, cache) {
|
|
2260
2324
|
const identifier = tokens.get(token);
|
|
2261
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
2262
|
-
if (
|
|
2263
|
-
|
|
2264
|
-
|
|
2325
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
|
|
2326
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
|
|
2327
|
+
if (!identifier) {
|
|
2328
|
+
// eslint-disable-next-line no-console
|
|
2329
|
+
console.log('Passed unknown unsubscribe token to unsubscribe', identifier);
|
|
2330
|
+
}
|
|
2265
2331
|
}
|
|
2266
2332
|
}
|
|
2267
2333
|
if (identifier) {
|
|
@@ -2369,9 +2435,11 @@ class NotificationManager {
|
|
|
2369
2435
|
}
|
|
2370
2436
|
})(!key || value === 'attributes' || value === 'relationships') : {};
|
|
2371
2437
|
if (!isStableIdentifier(identifier) && !isDocumentIdentifier(identifier)) {
|
|
2372
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
2373
|
-
|
|
2374
|
-
|
|
2438
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
|
|
2439
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
|
|
2440
|
+
// eslint-disable-next-line no-console
|
|
2441
|
+
console.log(`Notifying: Expected to receive a stable Identifier to notify '${value}' '${key || ''}' with, but ${String(identifier)} is not in the cache`, identifier);
|
|
2442
|
+
}
|
|
2375
2443
|
}
|
|
2376
2444
|
return false;
|
|
2377
2445
|
}
|
|
@@ -2383,16 +2451,22 @@ class NotificationManager {
|
|
|
2383
2451
|
this._buffered.set(identifier, buffer);
|
|
2384
2452
|
}
|
|
2385
2453
|
buffer.push([value, key]);
|
|
2386
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
2387
|
-
|
|
2454
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
|
|
2455
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
|
|
2456
|
+
count(`notify ${'type' in identifier ? identifier.type : '<document>'} ${value} ${key}`);
|
|
2457
|
+
}
|
|
2388
2458
|
}
|
|
2389
2459
|
if (!this._scheduleNotify()) {
|
|
2390
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
2391
|
-
|
|
2460
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
|
|
2461
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
|
|
2462
|
+
log('notify', 'buffered', `${'type' in identifier ? identifier.type : 'document'}`, identifier.lid, `${value}`, key || '');
|
|
2463
|
+
}
|
|
2392
2464
|
}
|
|
2393
2465
|
}
|
|
2394
|
-
} else if (macroCondition(getGlobalConfig().WarpDrive.
|
|
2395
|
-
|
|
2466
|
+
} else if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
|
|
2467
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
|
|
2468
|
+
count(`DISCARDED notify ${'type' in identifier ? identifier.type : '<document>'} ${value} ${key}`);
|
|
2469
|
+
}
|
|
2396
2470
|
}
|
|
2397
2471
|
return hasSubscribers;
|
|
2398
2472
|
}
|
|
@@ -2429,8 +2503,10 @@ class NotificationManager {
|
|
|
2429
2503
|
this._onFlushCB = undefined;
|
|
2430
2504
|
}
|
|
2431
2505
|
_flushNotification(identifier, value, key) {
|
|
2432
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
2433
|
-
|
|
2506
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
|
|
2507
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
|
|
2508
|
+
log('notify', '', `${'type' in identifier ? identifier.type : 'document'}`, identifier.lid, `${value}`, key || '');
|
|
2509
|
+
}
|
|
2434
2510
|
}
|
|
2435
2511
|
|
|
2436
2512
|
// TODO for documents this will need to switch based on Identifier kind
|
|
@@ -2776,7 +2852,7 @@ class IdentifierArray {
|
|
|
2776
2852
|
return false;
|
|
2777
2853
|
}
|
|
2778
2854
|
const original = target[index];
|
|
2779
|
-
const newIdentifier = extractIdentifierFromRecord$
|
|
2855
|
+
const newIdentifier = extractIdentifierFromRecord$2(value);
|
|
2780
2856
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2781
2857
|
if (!test) {
|
|
2782
2858
|
throw new Error(`Expected a record`);
|
|
@@ -2817,7 +2893,7 @@ class IdentifierArray {
|
|
|
2817
2893
|
return Reflect.deleteProperty(target, prop);
|
|
2818
2894
|
},
|
|
2819
2895
|
getPrototypeOf() {
|
|
2820
|
-
return
|
|
2896
|
+
return Array.prototype;
|
|
2821
2897
|
}
|
|
2822
2898
|
});
|
|
2823
2899
|
createArrayTags(proxy, _SIGNAL);
|
|
@@ -2960,7 +3036,7 @@ Collection.prototype.query = null;
|
|
|
2960
3036
|
// Ensure instanceof works correctly
|
|
2961
3037
|
// Object.setPrototypeOf(IdentifierArray.prototype, Array.prototype);
|
|
2962
3038
|
|
|
2963
|
-
function assertRecordPassedToHasMany(record) {
|
|
3039
|
+
function assertRecordPassedToHasMany$1(record) {
|
|
2964
3040
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2965
3041
|
if (!test) {
|
|
2966
3042
|
throw new Error(`All elements of a hasMany relationship must be instances of Model, you passed $${typeof record}`);
|
|
@@ -2974,11 +3050,11 @@ function assertRecordPassedToHasMany(record) {
|
|
|
2974
3050
|
}
|
|
2975
3051
|
}()) : {};
|
|
2976
3052
|
}
|
|
2977
|
-
function extractIdentifierFromRecord$
|
|
3053
|
+
function extractIdentifierFromRecord$2(record) {
|
|
2978
3054
|
if (!record) {
|
|
2979
3055
|
return null;
|
|
2980
3056
|
}
|
|
2981
|
-
assertRecordPassedToHasMany(record);
|
|
3057
|
+
assertRecordPassedToHasMany$1(record);
|
|
2982
3058
|
return recordIdentifierFor(record);
|
|
2983
3059
|
}
|
|
2984
3060
|
|
|
@@ -3073,6 +3149,9 @@ class RecordArrayManager {
|
|
|
3073
3149
|
sync(array, pending, this._set.get(array));
|
|
3074
3150
|
this._pending.delete(array);
|
|
3075
3151
|
}
|
|
3152
|
+
mutate(mutation) {
|
|
3153
|
+
this.store.cache.mutate(mutation);
|
|
3154
|
+
}
|
|
3076
3155
|
|
|
3077
3156
|
/**
|
|
3078
3157
|
Get the `RecordArray` for a modelName, which contains all loaded records of
|
|
@@ -3589,6 +3668,29 @@ function constructResource(type, id, lid) {
|
|
|
3589
3668
|
*/
|
|
3590
3669
|
// this import location is deprecated but breaks in 4.8 and older
|
|
3591
3670
|
|
|
3671
|
+
// @ts-expect-error adding to globalThis
|
|
3672
|
+
globalThis.setWarpDriveLogging = setLogging;
|
|
3673
|
+
|
|
3674
|
+
// @ts-expect-error adding to globalThis
|
|
3675
|
+
globalThis.getWarpDriveRuntimeConfig = getRuntimeConfig;
|
|
3676
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
|
|
3677
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
|
|
3678
|
+
// @ts-expect-error
|
|
3679
|
+
// eslint-disable-next-line
|
|
3680
|
+
globalThis.__WarpDriveMetricCountData = globalThis.__WarpDriveMetricCountData || {};
|
|
3681
|
+
// @ts-expect-error
|
|
3682
|
+
// eslint-disable-next-line
|
|
3683
|
+
globalThis.counts[label] = (globalThis.counts[label] || 0) + 1;
|
|
3684
|
+
|
|
3685
|
+
// @ts-expect-error
|
|
3686
|
+
globalThis.getWarpDriveMetricCounts = () => {
|
|
3687
|
+
// @ts-expect-error
|
|
3688
|
+
// eslint-disable-next-line
|
|
3689
|
+
return globalThis.__WarpDriveMetricCountData;
|
|
3690
|
+
};
|
|
3691
|
+
}
|
|
3692
|
+
}
|
|
3693
|
+
|
|
3592
3694
|
// `AwaitedKeys` is needed here to resolve any promise types like `PromiseBelongsTo`.
|
|
3593
3695
|
|
|
3594
3696
|
/**
|
|
@@ -3971,22 +4073,26 @@ class Store extends BaseClass {
|
|
|
3971
4073
|
opts.disableTestWaiter = typeof requestConfig.disableTestWaiter === 'boolean' ? requestConfig.disableTestWaiter : true;
|
|
3972
4074
|
}
|
|
3973
4075
|
}
|
|
3974
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
4076
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_REQUESTS)) {
|
|
4077
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_REQUESTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_REQUESTS) {
|
|
4078
|
+
let options;
|
|
4079
|
+
try {
|
|
4080
|
+
options = JSON.parse(JSON.stringify(requestConfig));
|
|
4081
|
+
} catch {
|
|
4082
|
+
options = requestConfig;
|
|
4083
|
+
}
|
|
4084
|
+
// eslint-disable-next-line no-console
|
|
4085
|
+
console.log(`request: [[START]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`, options);
|
|
3980
4086
|
}
|
|
3981
|
-
// eslint-disable-next-line no-console
|
|
3982
|
-
console.log(`request: [[START]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`, options);
|
|
3983
4087
|
}
|
|
3984
4088
|
const request = Object.assign({}, requestConfig, opts);
|
|
3985
4089
|
const future = this.requestManager.request(request);
|
|
3986
4090
|
future.onFinalize(() => {
|
|
3987
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
3988
|
-
|
|
3989
|
-
|
|
4091
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_REQUESTS)) {
|
|
4092
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_REQUESTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_REQUESTS) {
|
|
4093
|
+
// eslint-disable-next-line no-console
|
|
4094
|
+
console.log(`request: [[FINALIZE]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`);
|
|
4095
|
+
}
|
|
3990
4096
|
}
|
|
3991
4097
|
// skip flush for legacy belongsTo
|
|
3992
4098
|
if (requestConfig.op === 'findBelongsTo' && !requestConfig.url) {
|
|
@@ -4192,9 +4298,8 @@ class Store extends BaseClass {
|
|
|
4192
4298
|
This will cause the record to be destroyed and freed up for garbage collection.
|
|
4193
4299
|
Example
|
|
4194
4300
|
```javascript
|
|
4195
|
-
store.findRecord('post', '1')
|
|
4196
|
-
|
|
4197
|
-
});
|
|
4301
|
+
const { content: { data: post } } = await store.request(findRecord({ type: 'post', id: '1' }));
|
|
4302
|
+
store.unloadRecord(post);
|
|
4198
4303
|
```
|
|
4199
4304
|
@method unloadRecord
|
|
4200
4305
|
@public
|
|
@@ -5246,14 +5351,16 @@ class Store extends BaseClass {
|
|
|
5246
5351
|
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
5247
5352
|
assertDestroyingStore(this, '_push');
|
|
5248
5353
|
}
|
|
5249
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5354
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_PAYLOADS)) {
|
|
5355
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_PAYLOADS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_PAYLOADS) {
|
|
5356
|
+
try {
|
|
5357
|
+
const data = JSON.parse(JSON.stringify(jsonApiDoc));
|
|
5358
|
+
// eslint-disable-next-line no-console
|
|
5359
|
+
console.log('EmberData | Payload - push', data);
|
|
5360
|
+
} catch {
|
|
5361
|
+
// eslint-disable-next-line no-console
|
|
5362
|
+
console.log('EmberData | Payload - push', jsonApiDoc);
|
|
5363
|
+
}
|
|
5257
5364
|
}
|
|
5258
5365
|
}
|
|
5259
5366
|
if (asyncFlush) {
|
|
@@ -5476,9 +5583,9 @@ function normalizeProperties(store, identifier, properties) {
|
|
|
5476
5583
|
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
5477
5584
|
assertRecordsPassedToHasMany(properties[prop]);
|
|
5478
5585
|
}
|
|
5479
|
-
properties[prop] = extractIdentifiersFromRecords(properties[prop]);
|
|
5586
|
+
properties[prop] = extractIdentifiersFromRecords$1(properties[prop]);
|
|
5480
5587
|
} else if (field.kind === 'belongsTo') {
|
|
5481
|
-
properties[prop] = extractIdentifierFromRecord(properties[prop]);
|
|
5588
|
+
properties[prop] = extractIdentifierFromRecord$1(properties[prop]);
|
|
5482
5589
|
}
|
|
5483
5590
|
}
|
|
5484
5591
|
}
|
|
@@ -5506,10 +5613,10 @@ function assertRecordsPassedToHasMany(records) {
|
|
|
5506
5613
|
});
|
|
5507
5614
|
}()) : {};
|
|
5508
5615
|
}
|
|
5509
|
-
function extractIdentifiersFromRecords(records) {
|
|
5510
|
-
return records.map(record => extractIdentifierFromRecord(record));
|
|
5616
|
+
function extractIdentifiersFromRecords$1(records) {
|
|
5617
|
+
return records.map(record => extractIdentifierFromRecord$1(record));
|
|
5511
5618
|
}
|
|
5512
|
-
function extractIdentifierFromRecord(recordOrPromiseRecord) {
|
|
5619
|
+
function extractIdentifierFromRecord$1(recordOrPromiseRecord) {
|
|
5513
5620
|
if (!recordOrPromiseRecord) {
|
|
5514
5621
|
return null;
|
|
5515
5622
|
}
|
|
@@ -6157,4 +6264,475 @@ function fetchContentAndHydrate(next, context, identifier, priority) {
|
|
|
6157
6264
|
}]
|
|
6158
6265
|
});
|
|
6159
6266
|
}
|
|
6160
|
-
|
|
6267
|
+
|
|
6268
|
+
/**
|
|
6269
|
+
@module @ember-data/store
|
|
6270
|
+
*/
|
|
6271
|
+
/**
|
|
6272
|
+
A `ManyArray` is a `MutableArray` that represents the contents of a has-many
|
|
6273
|
+
relationship.
|
|
6274
|
+
|
|
6275
|
+
The `ManyArray` is instantiated lazily the first time the relationship is
|
|
6276
|
+
requested.
|
|
6277
|
+
|
|
6278
|
+
This class is not intended to be directly instantiated by consuming applications.
|
|
6279
|
+
|
|
6280
|
+
### Inverses
|
|
6281
|
+
|
|
6282
|
+
Often, the relationships in Ember Data applications will have
|
|
6283
|
+
an inverse. For example, imagine the following models are
|
|
6284
|
+
defined:
|
|
6285
|
+
|
|
6286
|
+
```app/models/post.js
|
|
6287
|
+
import Model, { hasMany } from '@ember-data/model';
|
|
6288
|
+
|
|
6289
|
+
export default class PostModel extends Model {
|
|
6290
|
+
@hasMany('comment') comments;
|
|
6291
|
+
}
|
|
6292
|
+
```
|
|
6293
|
+
|
|
6294
|
+
```app/models/comment.js
|
|
6295
|
+
import Model, { belongsTo } from '@ember-data/model';
|
|
6296
|
+
|
|
6297
|
+
export default class CommentModel extends Model {
|
|
6298
|
+
@belongsTo('post') post;
|
|
6299
|
+
}
|
|
6300
|
+
```
|
|
6301
|
+
|
|
6302
|
+
If you created a new instance of `Post` and added
|
|
6303
|
+
a `Comment` record to its `comments` has-many
|
|
6304
|
+
relationship, you would expect the comment's `post`
|
|
6305
|
+
property to be set to the post that contained
|
|
6306
|
+
the has-many.
|
|
6307
|
+
|
|
6308
|
+
We call the record to which a relationship belongs-to the
|
|
6309
|
+
relationship's _owner_.
|
|
6310
|
+
|
|
6311
|
+
@class ManyArray
|
|
6312
|
+
@public
|
|
6313
|
+
*/
|
|
6314
|
+
class RelatedCollection extends IdentifierArray {
|
|
6315
|
+
/**
|
|
6316
|
+
The loading state of this array
|
|
6317
|
+
@property {Boolean} isLoaded
|
|
6318
|
+
@public
|
|
6319
|
+
*/
|
|
6320
|
+
|
|
6321
|
+
/**
|
|
6322
|
+
`true` if the relationship is polymorphic, `false` otherwise.
|
|
6323
|
+
@property {Boolean} isPolymorphic
|
|
6324
|
+
@private
|
|
6325
|
+
*/
|
|
6326
|
+
|
|
6327
|
+
/**
|
|
6328
|
+
Metadata associated with the request for async hasMany relationships.
|
|
6329
|
+
Example
|
|
6330
|
+
Given that the server returns the following JSON payload when fetching a
|
|
6331
|
+
hasMany relationship:
|
|
6332
|
+
```js
|
|
6333
|
+
{
|
|
6334
|
+
"comments": [{
|
|
6335
|
+
"id": 1,
|
|
6336
|
+
"comment": "This is the first comment",
|
|
6337
|
+
}, {
|
|
6338
|
+
// ...
|
|
6339
|
+
}],
|
|
6340
|
+
"meta": {
|
|
6341
|
+
"page": 1,
|
|
6342
|
+
"total": 5
|
|
6343
|
+
}
|
|
6344
|
+
}
|
|
6345
|
+
```
|
|
6346
|
+
You can then access the meta data via the `meta` property:
|
|
6347
|
+
```js
|
|
6348
|
+
let comments = await post.comments;
|
|
6349
|
+
let meta = comments.meta;
|
|
6350
|
+
// meta.page => 1
|
|
6351
|
+
// meta.total => 5
|
|
6352
|
+
```
|
|
6353
|
+
@property {Object | null} meta
|
|
6354
|
+
@public
|
|
6355
|
+
*/
|
|
6356
|
+
|
|
6357
|
+
/**
|
|
6358
|
+
* Retrieve the links for this relationship
|
|
6359
|
+
*
|
|
6360
|
+
@property {Object | null} links
|
|
6361
|
+
@public
|
|
6362
|
+
*/
|
|
6363
|
+
|
|
6364
|
+
constructor(options) {
|
|
6365
|
+
super(options);
|
|
6366
|
+
this.isLoaded = options.isLoaded || false;
|
|
6367
|
+
this.isAsync = options.isAsync || false;
|
|
6368
|
+
this.isPolymorphic = options.isPolymorphic || false;
|
|
6369
|
+
this.identifier = options.identifier;
|
|
6370
|
+
this.key = options.key;
|
|
6371
|
+
}
|
|
6372
|
+
[MUTATE](target, receiver, prop, args, _SIGNAL) {
|
|
6373
|
+
switch (prop) {
|
|
6374
|
+
case 'length 0':
|
|
6375
|
+
{
|
|
6376
|
+
Reflect.set(target, 'length', 0);
|
|
6377
|
+
mutateReplaceRelatedRecords(this, [], _SIGNAL);
|
|
6378
|
+
return true;
|
|
6379
|
+
}
|
|
6380
|
+
case 'replace cell':
|
|
6381
|
+
{
|
|
6382
|
+
const [index, prior, value] = args;
|
|
6383
|
+
target[index] = value;
|
|
6384
|
+
mutateReplaceRelatedRecord(this, {
|
|
6385
|
+
value,
|
|
6386
|
+
prior,
|
|
6387
|
+
index
|
|
6388
|
+
}, _SIGNAL);
|
|
6389
|
+
return true;
|
|
6390
|
+
}
|
|
6391
|
+
case 'push':
|
|
6392
|
+
{
|
|
6393
|
+
const newValues = extractIdentifiersFromRecords(args);
|
|
6394
|
+
assertNoDuplicates(this, target, currentState => currentState.push(...newValues), `Cannot push duplicates to a hasMany's state.`);
|
|
6395
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
6396
|
+
// dedupe
|
|
6397
|
+
const seen = new Set(target);
|
|
6398
|
+
const unique = new Set();
|
|
6399
|
+
args.forEach(item => {
|
|
6400
|
+
const identifier = recordIdentifierFor(item);
|
|
6401
|
+
if (!seen.has(identifier)) {
|
|
6402
|
+
seen.add(identifier);
|
|
6403
|
+
unique.add(item);
|
|
6404
|
+
}
|
|
6405
|
+
});
|
|
6406
|
+
const newArgs = Array.from(unique);
|
|
6407
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
6408
|
+
if (newArgs.length) {
|
|
6409
|
+
mutateAddToRelatedRecords(this, {
|
|
6410
|
+
value: extractIdentifiersFromRecords(newArgs)
|
|
6411
|
+
}, _SIGNAL);
|
|
6412
|
+
}
|
|
6413
|
+
return result;
|
|
6414
|
+
}
|
|
6415
|
+
|
|
6416
|
+
// else, no dedupe, error on duplicates
|
|
6417
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6418
|
+
if (newValues.length) {
|
|
6419
|
+
mutateAddToRelatedRecords(this, {
|
|
6420
|
+
value: newValues
|
|
6421
|
+
}, _SIGNAL);
|
|
6422
|
+
}
|
|
6423
|
+
return result;
|
|
6424
|
+
}
|
|
6425
|
+
case 'pop':
|
|
6426
|
+
{
|
|
6427
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6428
|
+
if (result) {
|
|
6429
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
6430
|
+
value: recordIdentifierFor(result)
|
|
6431
|
+
}, _SIGNAL);
|
|
6432
|
+
}
|
|
6433
|
+
return result;
|
|
6434
|
+
}
|
|
6435
|
+
case 'unshift':
|
|
6436
|
+
{
|
|
6437
|
+
const newValues = extractIdentifiersFromRecords(args);
|
|
6438
|
+
assertNoDuplicates(this, target, currentState => currentState.unshift(...newValues), `Cannot unshift duplicates to a hasMany's state.`);
|
|
6439
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
6440
|
+
// dedupe
|
|
6441
|
+
const seen = new Set(target);
|
|
6442
|
+
const unique = new Set();
|
|
6443
|
+
args.forEach(item => {
|
|
6444
|
+
const identifier = recordIdentifierFor(item);
|
|
6445
|
+
if (!seen.has(identifier)) {
|
|
6446
|
+
seen.add(identifier);
|
|
6447
|
+
unique.add(item);
|
|
6448
|
+
}
|
|
6449
|
+
});
|
|
6450
|
+
const newArgs = Array.from(unique);
|
|
6451
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
6452
|
+
if (newArgs.length) {
|
|
6453
|
+
mutateAddToRelatedRecords(this, {
|
|
6454
|
+
value: extractIdentifiersFromRecords(newArgs),
|
|
6455
|
+
index: 0
|
|
6456
|
+
}, _SIGNAL);
|
|
6457
|
+
}
|
|
6458
|
+
return result;
|
|
6459
|
+
}
|
|
6460
|
+
|
|
6461
|
+
// else, no dedupe, error on duplicates
|
|
6462
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6463
|
+
if (newValues.length) {
|
|
6464
|
+
mutateAddToRelatedRecords(this, {
|
|
6465
|
+
value: newValues,
|
|
6466
|
+
index: 0
|
|
6467
|
+
}, _SIGNAL);
|
|
6468
|
+
}
|
|
6469
|
+
return result;
|
|
6470
|
+
}
|
|
6471
|
+
case 'shift':
|
|
6472
|
+
{
|
|
6473
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6474
|
+
if (result) {
|
|
6475
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
6476
|
+
value: recordIdentifierFor(result),
|
|
6477
|
+
index: 0
|
|
6478
|
+
}, _SIGNAL);
|
|
6479
|
+
}
|
|
6480
|
+
return result;
|
|
6481
|
+
}
|
|
6482
|
+
case 'sort':
|
|
6483
|
+
{
|
|
6484
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6485
|
+
mutateSortRelatedRecords(this, result.map(recordIdentifierFor), _SIGNAL);
|
|
6486
|
+
return result;
|
|
6487
|
+
}
|
|
6488
|
+
case 'splice':
|
|
6489
|
+
{
|
|
6490
|
+
const [start, deleteCount, ...adds] = args;
|
|
6491
|
+
|
|
6492
|
+
// detect a full replace
|
|
6493
|
+
if (start === 0 && deleteCount === this[SOURCE].length) {
|
|
6494
|
+
const newValues = extractIdentifiersFromRecords(adds);
|
|
6495
|
+
assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot replace a hasMany's state with a new state that contains duplicates.`);
|
|
6496
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
6497
|
+
// dedupe
|
|
6498
|
+
const current = new Set(adds);
|
|
6499
|
+
const unique = Array.from(current);
|
|
6500
|
+
const newArgs = [start, deleteCount].concat(unique);
|
|
6501
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
6502
|
+
mutateReplaceRelatedRecords(this, extractIdentifiersFromRecords(unique), _SIGNAL);
|
|
6503
|
+
return result;
|
|
6504
|
+
}
|
|
6505
|
+
|
|
6506
|
+
// else, no dedupe, error on duplicates
|
|
6507
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6508
|
+
mutateReplaceRelatedRecords(this, newValues, _SIGNAL);
|
|
6509
|
+
return result;
|
|
6510
|
+
}
|
|
6511
|
+
const newValues = extractIdentifiersFromRecords(adds);
|
|
6512
|
+
assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot splice a hasMany's state with a new state that contains duplicates.`);
|
|
6513
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
6514
|
+
// dedupe
|
|
6515
|
+
const currentState = target.slice();
|
|
6516
|
+
currentState.splice(start, deleteCount);
|
|
6517
|
+
const seen = new Set(currentState);
|
|
6518
|
+
const unique = [];
|
|
6519
|
+
adds.forEach(item => {
|
|
6520
|
+
const identifier = recordIdentifierFor(item);
|
|
6521
|
+
if (!seen.has(identifier)) {
|
|
6522
|
+
seen.add(identifier);
|
|
6523
|
+
unique.push(item);
|
|
6524
|
+
}
|
|
6525
|
+
});
|
|
6526
|
+
const newArgs = [start, deleteCount, ...unique];
|
|
6527
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
6528
|
+
if (deleteCount > 0) {
|
|
6529
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
6530
|
+
value: result.map(recordIdentifierFor),
|
|
6531
|
+
index: start
|
|
6532
|
+
}, _SIGNAL);
|
|
6533
|
+
}
|
|
6534
|
+
if (unique.length > 0) {
|
|
6535
|
+
mutateAddToRelatedRecords(this, {
|
|
6536
|
+
value: extractIdentifiersFromRecords(unique),
|
|
6537
|
+
index: start
|
|
6538
|
+
}, _SIGNAL);
|
|
6539
|
+
}
|
|
6540
|
+
return result;
|
|
6541
|
+
}
|
|
6542
|
+
|
|
6543
|
+
// else, no dedupe, error on duplicates
|
|
6544
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6545
|
+
if (deleteCount > 0) {
|
|
6546
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
6547
|
+
value: result.map(recordIdentifierFor),
|
|
6548
|
+
index: start
|
|
6549
|
+
}, _SIGNAL);
|
|
6550
|
+
}
|
|
6551
|
+
if (newValues.length > 0) {
|
|
6552
|
+
mutateAddToRelatedRecords(this, {
|
|
6553
|
+
value: newValues,
|
|
6554
|
+
index: start
|
|
6555
|
+
}, _SIGNAL);
|
|
6556
|
+
}
|
|
6557
|
+
return result;
|
|
6558
|
+
}
|
|
6559
|
+
default:
|
|
6560
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
6561
|
+
{
|
|
6562
|
+
throw new Error(`unable to convert ${prop} into a transaction that updates the cache state for this record array`);
|
|
6563
|
+
}
|
|
6564
|
+
})() : {};
|
|
6565
|
+
}
|
|
6566
|
+
}
|
|
6567
|
+
notify() {
|
|
6568
|
+
const signal = this[ARRAY_SIGNAL];
|
|
6569
|
+
signal.shouldReset = true;
|
|
6570
|
+
notifyArray(this);
|
|
6571
|
+
}
|
|
6572
|
+
|
|
6573
|
+
/**
|
|
6574
|
+
Reloads all of the records in the manyArray. If the manyArray
|
|
6575
|
+
holds a relationship that was originally fetched using a links url
|
|
6576
|
+
EmberData will revisit the original links url to repopulate the
|
|
6577
|
+
relationship.
|
|
6578
|
+
If the ManyArray holds the result of a `store.query()` reload will
|
|
6579
|
+
re-run the original query.
|
|
6580
|
+
Example
|
|
6581
|
+
```javascript
|
|
6582
|
+
let user = store.peekRecord('user', '1')
|
|
6583
|
+
await login(user);
|
|
6584
|
+
let permissions = await user.permissions;
|
|
6585
|
+
await permissions.reload();
|
|
6586
|
+
```
|
|
6587
|
+
@method reload
|
|
6588
|
+
@public
|
|
6589
|
+
*/
|
|
6590
|
+
reload(options) {
|
|
6591
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
6592
|
+
if (!test) {
|
|
6593
|
+
throw new Error(`Expected the manager for ManyArray to implement reloadHasMany`);
|
|
6594
|
+
}
|
|
6595
|
+
})(typeof this._manager.reloadHasMany === 'function') : {};
|
|
6596
|
+
// TODO this is odd, we don't ask the store for anything else like this?
|
|
6597
|
+
return this._manager.reloadHasMany(this.key, options);
|
|
6598
|
+
}
|
|
6599
|
+
|
|
6600
|
+
/**
|
|
6601
|
+
Saves all of the records in the `ManyArray`.
|
|
6602
|
+
Note: this API can only be used in legacy mode with a configured Adapter.
|
|
6603
|
+
Example
|
|
6604
|
+
```javascript
|
|
6605
|
+
const { content: { data: inbox } } = await store.request(findRecord({ type: 'inbox', id: '1' }));
|
|
6606
|
+
let messages = await inbox.messages;
|
|
6607
|
+
messages.forEach((message) => {
|
|
6608
|
+
message.isRead = true;
|
|
6609
|
+
});
|
|
6610
|
+
messages.save();
|
|
6611
|
+
```
|
|
6612
|
+
@method save
|
|
6613
|
+
@public
|
|
6614
|
+
@return {PromiseArray} promise
|
|
6615
|
+
*/
|
|
6616
|
+
|
|
6617
|
+
/**
|
|
6618
|
+
Create a child record within the owner
|
|
6619
|
+
@method createRecord
|
|
6620
|
+
@public
|
|
6621
|
+
@param {Object} hash
|
|
6622
|
+
@return {Model} record
|
|
6623
|
+
*/
|
|
6624
|
+
createRecord(hash) {
|
|
6625
|
+
const {
|
|
6626
|
+
store
|
|
6627
|
+
} = this;
|
|
6628
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
6629
|
+
if (!test) {
|
|
6630
|
+
throw new Error(`Expected modelName to be set`);
|
|
6631
|
+
}
|
|
6632
|
+
})(this.modelName) : {};
|
|
6633
|
+
const record = store.createRecord(this.modelName, hash);
|
|
6634
|
+
this.push(record);
|
|
6635
|
+
return record;
|
|
6636
|
+
}
|
|
6637
|
+
destroy() {
|
|
6638
|
+
super.destroy(false);
|
|
6639
|
+
}
|
|
6640
|
+
}
|
|
6641
|
+
RelatedCollection.prototype.isAsync = false;
|
|
6642
|
+
RelatedCollection.prototype.isPolymorphic = false;
|
|
6643
|
+
RelatedCollection.prototype.identifier = null;
|
|
6644
|
+
RelatedCollection.prototype.cache = null;
|
|
6645
|
+
RelatedCollection.prototype._inverseIsAsync = false;
|
|
6646
|
+
RelatedCollection.prototype.key = '';
|
|
6647
|
+
RelatedCollection.prototype.DEPRECATED_CLASS_NAME = 'ManyArray';
|
|
6648
|
+
function assertRecordPassedToHasMany(record) {
|
|
6649
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
6650
|
+
if (!test) {
|
|
6651
|
+
throw new Error(`All elements of a hasMany relationship must be instances of Model, you passed ${typeof record}`);
|
|
6652
|
+
}
|
|
6653
|
+
})(function () {
|
|
6654
|
+
try {
|
|
6655
|
+
recordIdentifierFor(record);
|
|
6656
|
+
return true;
|
|
6657
|
+
} catch {
|
|
6658
|
+
return false;
|
|
6659
|
+
}
|
|
6660
|
+
}()) : {};
|
|
6661
|
+
}
|
|
6662
|
+
function extractIdentifiersFromRecords(records) {
|
|
6663
|
+
return records.map(extractIdentifierFromRecord);
|
|
6664
|
+
}
|
|
6665
|
+
function extractIdentifierFromRecord(recordOrPromiseRecord) {
|
|
6666
|
+
assertRecordPassedToHasMany(recordOrPromiseRecord);
|
|
6667
|
+
return recordIdentifierFor(recordOrPromiseRecord);
|
|
6668
|
+
}
|
|
6669
|
+
function assertNoDuplicates(collection, target, callback, reason) {
|
|
6670
|
+
const state = target.slice();
|
|
6671
|
+
callback(state);
|
|
6672
|
+
if (state.length !== new Set(state).size) {
|
|
6673
|
+
const duplicates = state.filter((currentValue, currentIndex) => state.indexOf(currentValue) !== currentIndex);
|
|
6674
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
6675
|
+
deprecate(`${reason} This behavior is deprecated. Found duplicates for the following records within the new state provided to \`<${collection.identifier.type}:${collection.identifier.id || collection.identifier.lid}>.${collection.key}\`\n\t- ${Array.from(new Set(duplicates)).map(r => isStableIdentifier(r) ? r.lid : recordIdentifierFor(r).lid).sort((a, b) => a.localeCompare(b)).join('\n\t- ')}`, false, {
|
|
6676
|
+
id: 'ember-data:deprecate-many-array-duplicates',
|
|
6677
|
+
for: 'ember-data',
|
|
6678
|
+
until: '6.0',
|
|
6679
|
+
since: {
|
|
6680
|
+
enabled: '5.3',
|
|
6681
|
+
available: '4.13'
|
|
6682
|
+
}
|
|
6683
|
+
});
|
|
6684
|
+
} else {
|
|
6685
|
+
throw new Error(`${reason} Found duplicates for the following records within the new state provided to \`<${collection.identifier.type}:${collection.identifier.id || collection.identifier.lid}>.${collection.key}\`\n\t- ${Array.from(new Set(duplicates)).map(r => isStableIdentifier(r) ? r.lid : recordIdentifierFor(r).lid).sort((a, b) => a.localeCompare(b)).join('\n\t- ')}`);
|
|
6686
|
+
}
|
|
6687
|
+
}
|
|
6688
|
+
}
|
|
6689
|
+
function mutateAddToRelatedRecords(collection, operationInfo, _SIGNAL) {
|
|
6690
|
+
mutate(collection, {
|
|
6691
|
+
op: 'addToRelatedRecords',
|
|
6692
|
+
record: collection.identifier,
|
|
6693
|
+
field: collection.key,
|
|
6694
|
+
...operationInfo
|
|
6695
|
+
}, _SIGNAL);
|
|
6696
|
+
}
|
|
6697
|
+
function mutateRemoveFromRelatedRecords(collection, operationInfo, _SIGNAL) {
|
|
6698
|
+
mutate(collection, {
|
|
6699
|
+
op: 'removeFromRelatedRecords',
|
|
6700
|
+
record: collection.identifier,
|
|
6701
|
+
field: collection.key,
|
|
6702
|
+
...operationInfo
|
|
6703
|
+
}, _SIGNAL);
|
|
6704
|
+
}
|
|
6705
|
+
function mutateReplaceRelatedRecord(collection, operationInfo, _SIGNAL) {
|
|
6706
|
+
mutate(collection, {
|
|
6707
|
+
op: 'replaceRelatedRecord',
|
|
6708
|
+
record: collection.identifier,
|
|
6709
|
+
field: collection.key,
|
|
6710
|
+
...operationInfo
|
|
6711
|
+
}, _SIGNAL);
|
|
6712
|
+
}
|
|
6713
|
+
function mutateReplaceRelatedRecords(collection, value, _SIGNAL) {
|
|
6714
|
+
mutate(collection, {
|
|
6715
|
+
op: 'replaceRelatedRecords',
|
|
6716
|
+
record: collection.identifier,
|
|
6717
|
+
field: collection.key,
|
|
6718
|
+
value
|
|
6719
|
+
}, _SIGNAL);
|
|
6720
|
+
}
|
|
6721
|
+
function mutateSortRelatedRecords(collection, value, _SIGNAL) {
|
|
6722
|
+
mutate(collection, {
|
|
6723
|
+
op: 'sortRelatedRecords',
|
|
6724
|
+
record: collection.identifier,
|
|
6725
|
+
field: collection.key,
|
|
6726
|
+
value
|
|
6727
|
+
}, _SIGNAL);
|
|
6728
|
+
}
|
|
6729
|
+
function mutate(collection, mutation, _SIGNAL) {
|
|
6730
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
6731
|
+
if (!test) {
|
|
6732
|
+
throw new Error(`Expected the manager for ManyArray to implement mutate`);
|
|
6733
|
+
}
|
|
6734
|
+
})(typeof collection._manager.mutate === 'function') : {};
|
|
6735
|
+
collection._manager.mutate(mutation);
|
|
6736
|
+
addToTransaction(_SIGNAL);
|
|
6737
|
+
}
|
|
6738
|
+
export { ARRAY_SIGNAL as A, CacheHandler as C, IdentifierArray as I, MUTATE as M, RecordArrayManager as R, Store as S, _clearCaches as _, setIdentifierGenerationMethod as a, setIdentifierUpdateMethod as b, setIdentifierForgetMethod as c, setIdentifierResetMethod as d, setKeyInfoForResource as e, constructResource as f, coerceId as g, ensureStringId as h, isStableIdentifier as i, Collection as j, SOURCE as k, fastPush as l, removeRecordDataFor as m, notifyArray as n, setRecordIdentifier as o, peekCache as p, StoreMap as q, recordIdentifierFor as r, storeFor as s, setCacheFor as t, normalizeModelName as u, RelatedCollection as v, log as w, logGroup as x };
|