@ember-data/store 4.13.0-alpha.4 → 4.13.0-alpha.6
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/LICENSE.md +19 -7
- package/README.md +2 -2
- package/dist/{-private-C5j0gwYO.js → -private-uEHANwvx.js} +896 -160
- package/dist/-private-uEHANwvx.js.map +1 -0
- package/dist/-private.js +1 -1
- package/dist/index.js +1 -1
- package/logos/NCC-1701-a-blue.svg +4 -0
- package/logos/NCC-1701-a-gold.svg +4 -0
- package/logos/NCC-1701-a-gold_100.svg +1 -0
- package/logos/NCC-1701-a-gold_base-64.txt +1 -0
- package/logos/NCC-1701-a.svg +4 -0
- package/logos/README.md +4 -0
- package/logos/docs-badge.svg +2 -0
- package/logos/github-header.svg +444 -0
- package/logos/social1.png +0 -0
- package/logos/social2.png +0 -0
- package/logos/warp-drive-logo-dark.svg +4 -0
- package/logos/warp-drive-logo-gold.svg +4 -0
- package/package.json +23 -42
- package/unstable-preview-types/-private/legacy-model-support/shim-model-class.d.ts +3 -3
- package/unstable-preview-types/-private/legacy-model-support/shim-model-class.d.ts.map +1 -1
- 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 +1 -2
- 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 +61 -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/-types/q/ds-model.d.ts +3 -3
- package/unstable-preview-types/-types/q/ds-model.d.ts.map +1 -1
- package/unstable-preview-types/-types/q/schema-service.d.ts +5 -5
- package/unstable-preview-types/-types/q/schema-service.d.ts.map +1 -1
- package/unstable-preview-types/index.d.ts +25 -24
- package/dist/-private-C5j0gwYO.js.map +0 -1
- /package/{ember-data-logo-dark.svg → logos/ember-data-logo-dark.svg} +0 -0
- /package/{ember-data-logo-light.svg → logos/ember-data-logo-light.svg} +0 -0
|
@@ -2,8 +2,9 @@ import { deprecate, warn, assert } from '@ember/debug';
|
|
|
2
2
|
import { dasherize } from '@ember-data/request-utils/string';
|
|
3
3
|
import { macroCondition, getGlobalConfig, dependencySatisfies, importSync } from '@embroider/macros';
|
|
4
4
|
import { EnableHydration, SkipCache } from '@warp-drive/core-types/request';
|
|
5
|
+
import { setLogging, getRuntimeConfig } from '@warp-drive/core-types/runtime';
|
|
5
6
|
import { getOrSetGlobal, peekTransient, setTransient } from '@warp-drive/core-types/-private';
|
|
6
|
-
import { CACHE_OWNER, DEBUG_STALE_CACHE_OWNER,
|
|
7
|
+
import { CACHE_OWNER, DEBUG_STALE_CACHE_OWNER, DEBUG_IDENTIFIER_BUCKET, DEBUG_CLIENT_ORIGINATED } from '@warp-drive/core-types/identifier';
|
|
7
8
|
import { defineSignal, createSignal, subscribe, createArrayTags, addToTransaction, addTransactionCB } from '@ember-data/tracking/-private';
|
|
8
9
|
import { _backburner } from '@ember/runloop';
|
|
9
10
|
import { get, set } from '@ember/object';
|
|
@@ -316,9 +317,11 @@ class IdentifierCache {
|
|
|
316
317
|
*/
|
|
317
318
|
|
|
318
319
|
_getRecordIdentifier(resource, shouldGenerate) {
|
|
319
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
320
|
-
|
|
321
|
-
|
|
320
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
321
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
322
|
+
// eslint-disable-next-line no-console
|
|
323
|
+
console.groupCollapsed(`Identifiers: ${shouldGenerate ? 'Generating' : 'Peeking'} Identifier`, resource);
|
|
324
|
+
}
|
|
322
325
|
}
|
|
323
326
|
// short circuit if we're already the stable version
|
|
324
327
|
if (isStableIdentifier(resource)) {
|
|
@@ -328,33 +331,41 @@ class IdentifierCache {
|
|
|
328
331
|
throw new Error(`The supplied identifier ${JSON.stringify(resource)} does not belong to this store instance`);
|
|
329
332
|
}
|
|
330
333
|
}
|
|
331
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
334
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
335
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
336
|
+
// eslint-disable-next-line no-console
|
|
337
|
+
console.log(`Identifiers: cache HIT - Stable ${resource.lid}`);
|
|
338
|
+
// eslint-disable-next-line no-console
|
|
339
|
+
console.groupEnd();
|
|
340
|
+
}
|
|
336
341
|
}
|
|
337
342
|
return resource;
|
|
338
343
|
}
|
|
339
344
|
|
|
340
345
|
// the resource is unknown, ask the application to identify this data for us
|
|
341
346
|
const lid = this._generate(resource, 'record');
|
|
342
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
343
|
-
|
|
344
|
-
|
|
347
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
348
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
349
|
+
// eslint-disable-next-line no-console
|
|
350
|
+
console.log(`Identifiers: ${lid ? 'no ' : ''}lid ${lid ? lid + ' ' : ''}determined for resource`, resource);
|
|
351
|
+
}
|
|
345
352
|
}
|
|
346
353
|
let identifier = /*#__NOINLINE__*/getIdentifierFromLid(this._cache, lid, resource);
|
|
347
354
|
if (identifier !== null) {
|
|
348
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
349
|
-
|
|
350
|
-
|
|
355
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
356
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
357
|
+
// eslint-disable-next-line no-console
|
|
358
|
+
console.groupEnd();
|
|
359
|
+
}
|
|
351
360
|
}
|
|
352
361
|
return identifier;
|
|
353
362
|
}
|
|
354
363
|
if (shouldGenerate === 0) {
|
|
355
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
356
|
-
|
|
357
|
-
|
|
364
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
365
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
366
|
+
// eslint-disable-next-line no-console
|
|
367
|
+
console.groupEnd();
|
|
368
|
+
}
|
|
358
369
|
}
|
|
359
370
|
return;
|
|
360
371
|
}
|
|
@@ -372,9 +383,11 @@ class IdentifierCache {
|
|
|
372
383
|
identifier = /*#__NOINLINE__*/makeStableRecordIdentifier(keyInfo, 'record', false);
|
|
373
384
|
}
|
|
374
385
|
addResourceToCache(this._cache, identifier);
|
|
375
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
376
|
-
|
|
377
|
-
|
|
386
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
387
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
388
|
+
// eslint-disable-next-line no-console
|
|
389
|
+
console.groupEnd();
|
|
390
|
+
}
|
|
378
391
|
}
|
|
379
392
|
return identifier;
|
|
380
393
|
}
|
|
@@ -468,9 +481,11 @@ class IdentifierCache {
|
|
|
468
481
|
|
|
469
482
|
/*#__NOINLINE__*/
|
|
470
483
|
addResourceToCache(this._cache, identifier);
|
|
471
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
472
|
-
|
|
473
|
-
|
|
484
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
485
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
486
|
+
// eslint-disable-next-line no-console
|
|
487
|
+
console.log(`Identifiers: created identifier ${String(identifier)} for newly generated resource`, data);
|
|
488
|
+
}
|
|
474
489
|
}
|
|
475
490
|
return identifier;
|
|
476
491
|
}
|
|
@@ -517,9 +532,11 @@ class IdentifierCache {
|
|
|
517
532
|
if (hadLid) {
|
|
518
533
|
data.lid = identifier.lid;
|
|
519
534
|
}
|
|
520
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
521
|
-
|
|
522
|
-
|
|
535
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
536
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
537
|
+
// eslint-disable-next-line no-console
|
|
538
|
+
console.log(`Identifiers: merged identifiers ${generatedIdentifier.lid} and ${existingIdentifier.lid} for resource into ${identifier.lid}`, data);
|
|
539
|
+
}
|
|
523
540
|
}
|
|
524
541
|
}
|
|
525
542
|
const id = identifier.id;
|
|
@@ -529,9 +546,11 @@ class IdentifierCache {
|
|
|
529
546
|
|
|
530
547
|
// add to our own secondary lookup table
|
|
531
548
|
if (id !== newId && newId !== null) {
|
|
532
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
533
|
-
|
|
534
|
-
|
|
549
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
550
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
551
|
+
// eslint-disable-next-line no-console
|
|
552
|
+
console.log(`Identifiers: updated id for identifier ${identifier.lid} from '${String(id)}' to '${String(newId)}' for resource`, data);
|
|
553
|
+
}
|
|
535
554
|
}
|
|
536
555
|
const typeSet = this._cache.resourcesByType[identifier.type];
|
|
537
556
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
@@ -543,9 +562,11 @@ class IdentifierCache {
|
|
|
543
562
|
if (id !== null) {
|
|
544
563
|
typeSet.id.delete(id);
|
|
545
564
|
}
|
|
546
|
-
} else if (macroCondition(getGlobalConfig().WarpDrive.
|
|
547
|
-
|
|
548
|
-
|
|
565
|
+
} else if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
566
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
567
|
+
// eslint-disable-next-line no-console
|
|
568
|
+
console.log(`Identifiers: updated identifier ${identifier.lid} resource`, data);
|
|
569
|
+
}
|
|
549
570
|
}
|
|
550
571
|
return identifier;
|
|
551
572
|
}
|
|
@@ -628,9 +649,11 @@ class IdentifierCache {
|
|
|
628
649
|
}
|
|
629
650
|
identifier[CACHE_OWNER] = undefined;
|
|
630
651
|
this._forget(identifier, 'record');
|
|
631
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
632
|
-
|
|
633
|
-
|
|
652
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
653
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
654
|
+
// eslint-disable-next-line no-console
|
|
655
|
+
console.log(`Identifiers: released identifier ${identifierObject.lid}`);
|
|
656
|
+
}
|
|
634
657
|
}
|
|
635
658
|
}
|
|
636
659
|
destroy() {
|
|
@@ -646,15 +669,13 @@ function makeStableRecordIdentifier(recordIdentifier, bucket, clientOriginated)
|
|
|
646
669
|
// we enforce immutability in dev
|
|
647
670
|
// but preserve our ability to do controlled updates to the reference
|
|
648
671
|
let wrapper = {
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
},
|
|
672
|
+
type: recordIdentifier.type,
|
|
673
|
+
lid: recordIdentifier.lid,
|
|
652
674
|
get id() {
|
|
653
675
|
return recordIdentifier.id;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
},
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
const proto = {
|
|
658
679
|
get [CACHE_OWNER]() {
|
|
659
680
|
return recordIdentifier[CACHE_OWNER];
|
|
660
681
|
},
|
|
@@ -666,9 +687,15 @@ function makeStableRecordIdentifier(recordIdentifier, bucket, clientOriginated)
|
|
|
666
687
|
},
|
|
667
688
|
set [DEBUG_STALE_CACHE_OWNER](value) {
|
|
668
689
|
recordIdentifier[DEBUG_STALE_CACHE_OWNER] = value;
|
|
690
|
+
},
|
|
691
|
+
get [DEBUG_CLIENT_ORIGINATED]() {
|
|
692
|
+
return clientOriginated;
|
|
693
|
+
},
|
|
694
|
+
get [DEBUG_IDENTIFIER_BUCKET]() {
|
|
695
|
+
return bucket;
|
|
669
696
|
}
|
|
670
697
|
};
|
|
671
|
-
Object.defineProperty(
|
|
698
|
+
Object.defineProperty(proto, 'toString', {
|
|
672
699
|
enumerable: false,
|
|
673
700
|
value: () => {
|
|
674
701
|
const {
|
|
@@ -679,7 +706,7 @@ function makeStableRecordIdentifier(recordIdentifier, bucket, clientOriginated)
|
|
|
679
706
|
return `${clientOriginated ? '[CLIENT_ORIGINATED] ' : ''}${String(type)}:${String(id)} (${lid})`;
|
|
680
707
|
}
|
|
681
708
|
});
|
|
682
|
-
Object.defineProperty(
|
|
709
|
+
Object.defineProperty(proto, 'toJSON', {
|
|
683
710
|
enumerable: false,
|
|
684
711
|
value: () => {
|
|
685
712
|
const {
|
|
@@ -694,8 +721,7 @@ function makeStableRecordIdentifier(recordIdentifier, bucket, clientOriginated)
|
|
|
694
721
|
};
|
|
695
722
|
}
|
|
696
723
|
});
|
|
697
|
-
wrapper
|
|
698
|
-
wrapper[DEBUG_IDENTIFIER_BUCKET] = bucket;
|
|
724
|
+
Object.setPrototypeOf(wrapper, proto);
|
|
699
725
|
DEBUG_MAP.set(wrapper, recordIdentifier);
|
|
700
726
|
wrapper = freeze(wrapper);
|
|
701
727
|
return wrapper;
|
|
@@ -778,9 +804,11 @@ function detectMerge(cache, keyInfo, identifier, data) {
|
|
|
778
804
|
}
|
|
779
805
|
function getIdentifierFromLid(cache, lid, resource) {
|
|
780
806
|
const identifier = cache.resources.get(lid);
|
|
781
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
782
|
-
|
|
783
|
-
|
|
807
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
808
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
809
|
+
// eslint-disable-next-line no-console
|
|
810
|
+
console.log(`Identifiers: cache ${identifier ? 'HIT' : 'MISS'} - Non-Stable ${lid}`, resource);
|
|
811
|
+
}
|
|
784
812
|
}
|
|
785
813
|
return identifier || null;
|
|
786
814
|
}
|
|
@@ -1336,14 +1364,16 @@ class InstanceCache {
|
|
|
1336
1364
|
setCacheFor(record, cache);
|
|
1337
1365
|
StoreMap.set(record, this.store);
|
|
1338
1366
|
this.__instances.record.set(identifier, record);
|
|
1339
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1367
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1368
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1369
|
+
logGroup('reactive-ui', '', identifier.type, identifier.lid, 'created', '');
|
|
1370
|
+
// eslint-disable-next-line no-console
|
|
1371
|
+
console.log({
|
|
1372
|
+
properties
|
|
1373
|
+
});
|
|
1374
|
+
// eslint-disable-next-line no-console
|
|
1375
|
+
console.groupEnd();
|
|
1376
|
+
}
|
|
1347
1377
|
}
|
|
1348
1378
|
}
|
|
1349
1379
|
return record;
|
|
@@ -1389,8 +1419,10 @@ class InstanceCache {
|
|
|
1389
1419
|
this.store.identifierCache.forgetRecordIdentifier(identifier);
|
|
1390
1420
|
removeRecordDataFor(identifier);
|
|
1391
1421
|
this.store._requestCache._clearEntries(identifier);
|
|
1392
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1393
|
-
|
|
1422
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1423
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1424
|
+
log('reactive-ui', '', identifier.type, identifier.lid, 'disconnected', '');
|
|
1425
|
+
}
|
|
1394
1426
|
}
|
|
1395
1427
|
}
|
|
1396
1428
|
unloadRecord(identifier) {
|
|
@@ -1406,9 +1438,11 @@ class InstanceCache {
|
|
|
1406
1438
|
})() : {};
|
|
1407
1439
|
}
|
|
1408
1440
|
}
|
|
1409
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1410
|
-
|
|
1411
|
-
|
|
1441
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1442
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1443
|
+
// eslint-disable-next-line no-console
|
|
1444
|
+
console.groupCollapsed(`InstanceCache: unloading record for ${String(identifier)}`);
|
|
1445
|
+
}
|
|
1412
1446
|
}
|
|
1413
1447
|
|
|
1414
1448
|
// TODO is this join still necessary?
|
|
@@ -1421,27 +1455,33 @@ class InstanceCache {
|
|
|
1421
1455
|
StoreMap.delete(record);
|
|
1422
1456
|
RecordCache.delete(record);
|
|
1423
1457
|
removeRecordDataFor(record);
|
|
1424
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1425
|
-
|
|
1426
|
-
|
|
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 record for ${String(identifier)}`);
|
|
1462
|
+
}
|
|
1427
1463
|
}
|
|
1428
1464
|
}
|
|
1429
1465
|
if (cache) {
|
|
1430
1466
|
cache.unloadRecord(identifier);
|
|
1431
1467
|
removeRecordDataFor(identifier);
|
|
1432
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1433
|
-
|
|
1434
|
-
|
|
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: destroyed cache for ${String(identifier)}`);
|
|
1472
|
+
}
|
|
1435
1473
|
}
|
|
1436
1474
|
} else {
|
|
1437
1475
|
this.disconnect(identifier);
|
|
1438
1476
|
}
|
|
1439
1477
|
this.store._requestCache._clearEntries(identifier);
|
|
1440
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1478
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1479
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1480
|
+
// eslint-disable-next-line no-console
|
|
1481
|
+
console.log(`InstanceCache: unloaded RecordData for ${String(identifier)}`);
|
|
1482
|
+
// eslint-disable-next-line no-console
|
|
1483
|
+
console.groupEnd();
|
|
1484
|
+
}
|
|
1445
1485
|
}
|
|
1446
1486
|
});
|
|
1447
1487
|
}
|
|
@@ -1496,9 +1536,11 @@ class InstanceCache {
|
|
|
1496
1536
|
warn(`Your ${type} record was saved to the server, but the response does not have an id.`, !(oldId !== null && id === null));
|
|
1497
1537
|
return;
|
|
1498
1538
|
}
|
|
1499
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1500
|
-
|
|
1501
|
-
|
|
1539
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1540
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1541
|
+
// eslint-disable-next-line no-console
|
|
1542
|
+
console.log(`InstanceCache: updating id to '${id}' for record ${String(identifier)}`);
|
|
1543
|
+
}
|
|
1502
1544
|
}
|
|
1503
1545
|
const existingIdentifier = this.store.identifierCache.peekRecordIdentifier({
|
|
1504
1546
|
type,
|
|
@@ -1815,7 +1857,9 @@ class CacheManager {
|
|
|
1815
1857
|
peek(identifier) {
|
|
1816
1858
|
return this.#cache.peek(identifier);
|
|
1817
1859
|
}
|
|
1818
|
-
|
|
1860
|
+
peekRemoteState(identifier) {
|
|
1861
|
+
return this.#cache.peekRemoteState(identifier);
|
|
1862
|
+
}
|
|
1819
1863
|
/**
|
|
1820
1864
|
* Peek the Cache for the existing request data associated with
|
|
1821
1865
|
* a cacheable request
|
|
@@ -2038,6 +2082,19 @@ class CacheManager {
|
|
|
2038
2082
|
return this.#cache.getAttr(identifier, propertyName);
|
|
2039
2083
|
}
|
|
2040
2084
|
|
|
2085
|
+
/**
|
|
2086
|
+
* Retrieve the remote state for an attribute from the cache
|
|
2087
|
+
*
|
|
2088
|
+
* @method getRemoteAttr
|
|
2089
|
+
* @public
|
|
2090
|
+
* @param identifier
|
|
2091
|
+
* @param propertyName
|
|
2092
|
+
* @return {unknown}
|
|
2093
|
+
*/
|
|
2094
|
+
getRemoteAttr(identifier, propertyName) {
|
|
2095
|
+
return this.#cache.getRemoteAttr(identifier, propertyName);
|
|
2096
|
+
}
|
|
2097
|
+
|
|
2041
2098
|
/**
|
|
2042
2099
|
* Mutate the data for an attribute in the cache
|
|
2043
2100
|
*
|
|
@@ -2162,6 +2219,19 @@ class CacheManager {
|
|
|
2162
2219
|
return this.#cache.getRelationship(identifier, propertyName);
|
|
2163
2220
|
}
|
|
2164
2221
|
|
|
2222
|
+
/**
|
|
2223
|
+
* Query the cache for the remote state of a relationship property
|
|
2224
|
+
*
|
|
2225
|
+
* @method getRelationship
|
|
2226
|
+
* @public
|
|
2227
|
+
* @param identifier
|
|
2228
|
+
* @param propertyName
|
|
2229
|
+
* @return resource relationship object
|
|
2230
|
+
*/
|
|
2231
|
+
getRemoteRelationship(identifier, propertyName) {
|
|
2232
|
+
return this.#cache.getRemoteRelationship(identifier, propertyName);
|
|
2233
|
+
}
|
|
2234
|
+
|
|
2165
2235
|
// Resource State
|
|
2166
2236
|
// ===============
|
|
2167
2237
|
|
|
@@ -2246,10 +2316,8 @@ class CacheManager {
|
|
|
2246
2316
|
* @module @ember-data/store
|
|
2247
2317
|
*/
|
|
2248
2318
|
|
|
2249
|
-
let tokenId = 0;
|
|
2250
|
-
const CacheOperations = new Set(['added', 'removed', 'state', 'updated', 'invalidated']);
|
|
2251
2319
|
function isCacheOperationValue(value) {
|
|
2252
|
-
return
|
|
2320
|
+
return value === 'added' || value === 'state' || value === 'updated' || value === 'removed' || value === 'invalidated';
|
|
2253
2321
|
}
|
|
2254
2322
|
function runLoopIsFlushing() {
|
|
2255
2323
|
//@ts-expect-error
|
|
@@ -2258,23 +2326,41 @@ function runLoopIsFlushing() {
|
|
|
2258
2326
|
function count(label) {
|
|
2259
2327
|
// @ts-expect-error
|
|
2260
2328
|
// eslint-disable-next-line
|
|
2261
|
-
globalThis.
|
|
2262
|
-
// @ts-expect-error
|
|
2263
|
-
// eslint-disable-next-line
|
|
2264
|
-
globalThis.counts[label] = (globalThis.counts[label] || 0) + 1;
|
|
2329
|
+
globalThis.__WarpDriveMetricCountData[label] = (globalThis.__WarpDriveMetricCountData[label] || 0) + 1;
|
|
2265
2330
|
}
|
|
2266
|
-
function
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2331
|
+
function asInternalToken(token) {
|
|
2332
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2333
|
+
if (!test) {
|
|
2334
|
+
throw new Error(`Expected a token with a 'for' property`);
|
|
2335
|
+
}
|
|
2336
|
+
})(token && typeof token === 'function' && 'for' in token) : {};
|
|
2337
|
+
}
|
|
2338
|
+
function _unsubscribe(token, cache) {
|
|
2339
|
+
asInternalToken(token);
|
|
2340
|
+
const identifier = token.for;
|
|
2341
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
|
|
2342
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
|
|
2343
|
+
if (!identifier) {
|
|
2344
|
+
// eslint-disable-next-line no-console
|
|
2345
|
+
console.log('Passed unknown unsubscribe token to unsubscribe', identifier);
|
|
2346
|
+
}
|
|
2272
2347
|
}
|
|
2273
2348
|
}
|
|
2274
2349
|
if (identifier) {
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2350
|
+
const callbacks = cache.get(identifier);
|
|
2351
|
+
if (!callbacks) {
|
|
2352
|
+
return;
|
|
2353
|
+
}
|
|
2354
|
+
const index = callbacks.indexOf(token);
|
|
2355
|
+
if (index === -1) {
|
|
2356
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2357
|
+
if (!test) {
|
|
2358
|
+
throw new Error(`Cannot unsubscribe a token that is not subscribed`);
|
|
2359
|
+
}
|
|
2360
|
+
})(index !== -1) : {};
|
|
2361
|
+
return;
|
|
2362
|
+
}
|
|
2363
|
+
callbacks.splice(index, 1);
|
|
2278
2364
|
}
|
|
2279
2365
|
}
|
|
2280
2366
|
|
|
@@ -2295,7 +2381,6 @@ class NotificationManager {
|
|
|
2295
2381
|
this._buffered = new Map();
|
|
2296
2382
|
this._hasFlush = false;
|
|
2297
2383
|
this._cache = new Map();
|
|
2298
|
-
this._tokens = new Map();
|
|
2299
2384
|
}
|
|
2300
2385
|
|
|
2301
2386
|
/**
|
|
@@ -2332,17 +2417,26 @@ class NotificationManager {
|
|
|
2332
2417
|
throw new Error(`Expected to receive a stable Identifier to subscribe to`);
|
|
2333
2418
|
}
|
|
2334
2419
|
})(identifier === 'resource' || identifier === 'document' || isStableIdentifier(identifier) || isDocumentIdentifier(identifier)) : {};
|
|
2335
|
-
let
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2420
|
+
let callbacks = this._cache.get(identifier);
|
|
2421
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2422
|
+
if (!test) {
|
|
2423
|
+
throw new Error(`expected to receive a valid callback`);
|
|
2424
|
+
}
|
|
2425
|
+
})(typeof callback === 'function') : {};
|
|
2426
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2427
|
+
if (!test) {
|
|
2428
|
+
throw new Error(`cannot subscribe with the same callback twice`);
|
|
2429
|
+
}
|
|
2430
|
+
})(!callbacks || !callbacks.includes(callback)) : {};
|
|
2431
|
+
// we use the callback as the cancellation token
|
|
2432
|
+
//@ts-expect-error
|
|
2433
|
+
callback.for = identifier;
|
|
2434
|
+
if (!callbacks) {
|
|
2435
|
+
callbacks = [];
|
|
2436
|
+
this._cache.set(identifier, callbacks);
|
|
2339
2437
|
}
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
} : {};
|
|
2343
|
-
map.set(unsubToken, callback);
|
|
2344
|
-
this._tokens.set(unsubToken, identifier);
|
|
2345
|
-
return unsubToken;
|
|
2438
|
+
callbacks.push(callback);
|
|
2439
|
+
return callback;
|
|
2346
2440
|
}
|
|
2347
2441
|
|
|
2348
2442
|
/**
|
|
@@ -2354,7 +2448,7 @@ class NotificationManager {
|
|
|
2354
2448
|
*/
|
|
2355
2449
|
unsubscribe(token) {
|
|
2356
2450
|
if (!this.isDestroyed) {
|
|
2357
|
-
_unsubscribe(
|
|
2451
|
+
_unsubscribe(token, this._cache);
|
|
2358
2452
|
}
|
|
2359
2453
|
}
|
|
2360
2454
|
|
|
@@ -2376,13 +2470,15 @@ class NotificationManager {
|
|
|
2376
2470
|
}
|
|
2377
2471
|
})(!key || value === 'attributes' || value === 'relationships') : {};
|
|
2378
2472
|
if (!isStableIdentifier(identifier) && !isDocumentIdentifier(identifier)) {
|
|
2379
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
2380
|
-
|
|
2381
|
-
|
|
2473
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
|
|
2474
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
|
|
2475
|
+
// eslint-disable-next-line no-console
|
|
2476
|
+
console.log(`Notifying: Expected to receive a stable Identifier to notify '${value}' '${key || ''}' with, but ${String(identifier)} is not in the cache`, identifier);
|
|
2477
|
+
}
|
|
2382
2478
|
}
|
|
2383
2479
|
return false;
|
|
2384
2480
|
}
|
|
2385
|
-
const hasSubscribers = Boolean(this._cache.get(identifier)?.
|
|
2481
|
+
const hasSubscribers = Boolean(this._cache.get(identifier)?.length);
|
|
2386
2482
|
if (isCacheOperationValue(value) || hasSubscribers) {
|
|
2387
2483
|
let buffer = this._buffered.get(identifier);
|
|
2388
2484
|
if (!buffer) {
|
|
@@ -2390,16 +2486,29 @@ class NotificationManager {
|
|
|
2390
2486
|
this._buffered.set(identifier, buffer);
|
|
2391
2487
|
}
|
|
2392
2488
|
buffer.push([value, key]);
|
|
2393
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
2394
|
-
|
|
2489
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
|
|
2490
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
|
|
2491
|
+
count(`notify ${'type' in identifier ? identifier.type : '<document>'} ${value} ${key}`);
|
|
2492
|
+
}
|
|
2395
2493
|
}
|
|
2396
2494
|
if (!this._scheduleNotify()) {
|
|
2397
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
2398
|
-
|
|
2495
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
|
|
2496
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
|
|
2497
|
+
log('notify', 'buffered', `${'type' in identifier ? identifier.type : 'document'}`, identifier.lid, `${value}`, key || '');
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
}
|
|
2501
|
+
} else {
|
|
2502
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
|
|
2503
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
|
|
2504
|
+
log('notify', 'discarded', `${'type' in identifier ? identifier.type : 'document'}`, identifier.lid, `${value}`, key || '');
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
2507
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
|
|
2508
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
|
|
2509
|
+
count(`DISCARDED notify ${'type' in identifier ? identifier.type : '<document>'} ${value} ${key}`);
|
|
2399
2510
|
}
|
|
2400
2511
|
}
|
|
2401
|
-
} else if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS)) {
|
|
2402
|
-
count(`DISCARDED notify ${'type' in identifier ? identifier.type : '<document>'} ${value} ${key}`);
|
|
2403
2512
|
}
|
|
2404
2513
|
return hasSubscribers;
|
|
2405
2514
|
}
|
|
@@ -2436,8 +2545,10 @@ class NotificationManager {
|
|
|
2436
2545
|
this._onFlushCB = undefined;
|
|
2437
2546
|
}
|
|
2438
2547
|
_flushNotification(identifier, value, key) {
|
|
2439
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
2440
|
-
|
|
2548
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
|
|
2549
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
|
|
2550
|
+
log('notify', '', `${'type' in identifier ? identifier.type : 'document'}`, identifier.lid, `${value}`, key || '');
|
|
2551
|
+
}
|
|
2441
2552
|
}
|
|
2442
2553
|
|
|
2443
2554
|
// TODO for documents this will need to switch based on Identifier kind
|
|
@@ -2449,11 +2560,11 @@ class NotificationManager {
|
|
|
2449
2560
|
});
|
|
2450
2561
|
}
|
|
2451
2562
|
}
|
|
2452
|
-
const
|
|
2453
|
-
if (!
|
|
2563
|
+
const callbacks = this._cache.get(identifier);
|
|
2564
|
+
if (!callbacks || !callbacks.length) {
|
|
2454
2565
|
return false;
|
|
2455
2566
|
}
|
|
2456
|
-
|
|
2567
|
+
callbacks.forEach(cb => {
|
|
2457
2568
|
// @ts-expect-error overload doesn't narrow within body
|
|
2458
2569
|
cb(identifier, value, key);
|
|
2459
2570
|
});
|
|
@@ -2461,7 +2572,6 @@ class NotificationManager {
|
|
|
2461
2572
|
}
|
|
2462
2573
|
destroy() {
|
|
2463
2574
|
this.isDestroyed = true;
|
|
2464
|
-
this._tokens.clear();
|
|
2465
2575
|
this._cache.clear();
|
|
2466
2576
|
}
|
|
2467
2577
|
}
|
|
@@ -2976,7 +3086,7 @@ class IdentifierArray {
|
|
|
2976
3086
|
return false;
|
|
2977
3087
|
}
|
|
2978
3088
|
const original = target[index];
|
|
2979
|
-
const newIdentifier = extractIdentifierFromRecord$
|
|
3089
|
+
const newIdentifier = extractIdentifierFromRecord$2(value);
|
|
2980
3090
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2981
3091
|
if (!test) {
|
|
2982
3092
|
throw new Error(`Expected a record`);
|
|
@@ -3017,7 +3127,7 @@ class IdentifierArray {
|
|
|
3017
3127
|
return Reflect.deleteProperty(target, prop);
|
|
3018
3128
|
},
|
|
3019
3129
|
getPrototypeOf() {
|
|
3020
|
-
return
|
|
3130
|
+
return Array.prototype;
|
|
3021
3131
|
}
|
|
3022
3132
|
});
|
|
3023
3133
|
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_A_USAGE)) {
|
|
@@ -3048,6 +3158,15 @@ class IdentifierArray {
|
|
|
3048
3158
|
})() : {};
|
|
3049
3159
|
};
|
|
3050
3160
|
}
|
|
3161
|
+
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
3162
|
+
Object.defineProperty(this, '__SHOW_ME_THE_DATA_(debug mode only)__', {
|
|
3163
|
+
enumerable: false,
|
|
3164
|
+
configurable: true,
|
|
3165
|
+
get() {
|
|
3166
|
+
return proxy.slice();
|
|
3167
|
+
}
|
|
3168
|
+
});
|
|
3169
|
+
}
|
|
3051
3170
|
createArrayTags(proxy, _SIGNAL);
|
|
3052
3171
|
this[NOTIFY] = this[NOTIFY].bind(proxy);
|
|
3053
3172
|
return proxy;
|
|
@@ -3599,7 +3718,7 @@ if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_ARRAY_LIKE
|
|
|
3599
3718
|
// @ts-expect-error
|
|
3600
3719
|
IdentifierArray.prototype.lastObject = null;
|
|
3601
3720
|
}
|
|
3602
|
-
function assertRecordPassedToHasMany(record) {
|
|
3721
|
+
function assertRecordPassedToHasMany$1(record) {
|
|
3603
3722
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
3604
3723
|
if (!test) {
|
|
3605
3724
|
throw new Error(`All elements of a hasMany relationship must be instances of Model, you passed $${typeof record}`);
|
|
@@ -3613,24 +3732,24 @@ function assertRecordPassedToHasMany(record) {
|
|
|
3613
3732
|
}
|
|
3614
3733
|
}()) : {};
|
|
3615
3734
|
}
|
|
3616
|
-
function extractIdentifierFromRecord$
|
|
3735
|
+
function extractIdentifierFromRecord$2(recordOrPromiseRecord) {
|
|
3617
3736
|
if (!recordOrPromiseRecord) {
|
|
3618
3737
|
return null;
|
|
3619
3738
|
}
|
|
3620
|
-
if (isPromiseRecord$
|
|
3739
|
+
if (isPromiseRecord$2(recordOrPromiseRecord)) {
|
|
3621
3740
|
const content = recordOrPromiseRecord.content;
|
|
3622
3741
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
3623
3742
|
if (!test) {
|
|
3624
3743
|
throw new Error('You passed in a promise that did not originate from an EmberData relationship. You can only pass promises that come from a belongsTo relationship.');
|
|
3625
3744
|
}
|
|
3626
3745
|
})(content !== undefined && content !== null) : {};
|
|
3627
|
-
assertRecordPassedToHasMany(content);
|
|
3746
|
+
assertRecordPassedToHasMany$1(content);
|
|
3628
3747
|
return recordIdentifierFor(content);
|
|
3629
3748
|
}
|
|
3630
|
-
assertRecordPassedToHasMany(recordOrPromiseRecord);
|
|
3749
|
+
assertRecordPassedToHasMany$1(recordOrPromiseRecord);
|
|
3631
3750
|
return recordIdentifierFor(recordOrPromiseRecord);
|
|
3632
3751
|
}
|
|
3633
|
-
function isPromiseRecord$
|
|
3752
|
+
function isPromiseRecord$2(record) {
|
|
3634
3753
|
return Boolean(typeof record === 'object' && record && 'then' in record);
|
|
3635
3754
|
}
|
|
3636
3755
|
|
|
@@ -3725,6 +3844,9 @@ class RecordArrayManager {
|
|
|
3725
3844
|
sync(array, pending, this._set.get(array));
|
|
3726
3845
|
this._pending.delete(array);
|
|
3727
3846
|
}
|
|
3847
|
+
mutate(mutation) {
|
|
3848
|
+
this.store.cache.mutate(mutation);
|
|
3849
|
+
}
|
|
3728
3850
|
|
|
3729
3851
|
/**
|
|
3730
3852
|
Get the `RecordArray` for a modelName, which contains all loaded records of
|
|
@@ -4241,6 +4363,118 @@ function constructResource(type, id, lid) {
|
|
|
4241
4363
|
*/
|
|
4242
4364
|
// this import location is deprecated but breaks in 4.8 and older
|
|
4243
4365
|
|
|
4366
|
+
// @ts-expect-error adding to globalThis
|
|
4367
|
+
globalThis.setWarpDriveLogging = setLogging;
|
|
4368
|
+
|
|
4369
|
+
// @ts-expect-error adding to globalThis
|
|
4370
|
+
globalThis.getWarpDriveRuntimeConfig = getRuntimeConfig;
|
|
4371
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
|
|
4372
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
|
|
4373
|
+
// @ts-expect-error adding to globalThis
|
|
4374
|
+
// eslint-disable-next-line
|
|
4375
|
+
globalThis.__WarpDriveMetricCountData = globalThis.__WarpDriveMetricCountData || {};
|
|
4376
|
+
|
|
4377
|
+
// @ts-expect-error adding to globalThis
|
|
4378
|
+
globalThis.getWarpDriveMetricCounts = () => {
|
|
4379
|
+
// @ts-expect-error
|
|
4380
|
+
// eslint-disable-next-line
|
|
4381
|
+
return structuredClone(globalThis.__WarpDriveMetricCountData);
|
|
4382
|
+
};
|
|
4383
|
+
|
|
4384
|
+
// @ts-expect-error adding to globalThis
|
|
4385
|
+
globalThis.resetWarpDriveMetricCounts = () => {
|
|
4386
|
+
// @ts-expect-error
|
|
4387
|
+
globalThis.__WarpDriveMetricCountData = {};
|
|
4388
|
+
};
|
|
4389
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.__INTERNAL_LOG_NATIVE_MAP_SET_COUNTS)) {
|
|
4390
|
+
if (getGlobalConfig().WarpDrive.debug.__INTERNAL_LOG_NATIVE_MAP_SET_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.__INTERNAL_LOG_NATIVE_MAP_SET_COUNTS) {
|
|
4391
|
+
// @ts-expect-error adding to globalThis
|
|
4392
|
+
globalThis.__primitiveInstanceId = 0;
|
|
4393
|
+
function interceptAndLog(klassName, methodName) {
|
|
4394
|
+
const klass = globalThis[klassName];
|
|
4395
|
+
if (methodName === 'constructor') {
|
|
4396
|
+
const instantiationLabel = `new ${klassName}()`;
|
|
4397
|
+
// @ts-expect-error
|
|
4398
|
+
globalThis[klassName] = class extends klass {
|
|
4399
|
+
// @ts-expect-error
|
|
4400
|
+
constructor(...args) {
|
|
4401
|
+
// eslint-disable-next-line
|
|
4402
|
+
super(...args);
|
|
4403
|
+
// @ts-expect-error
|
|
4404
|
+
|
|
4405
|
+
const instanceId = globalThis.__primitiveInstanceId++;
|
|
4406
|
+
// @ts-expect-error
|
|
4407
|
+
// eslint-disable-next-line
|
|
4408
|
+
globalThis.__WarpDriveMetricCountData[instantiationLabel] =
|
|
4409
|
+
// @ts-expect-error
|
|
4410
|
+
// eslint-disable-next-line
|
|
4411
|
+
(globalThis.__WarpDriveMetricCountData[instantiationLabel] || 0) + 1;
|
|
4412
|
+
// @ts-expect-error
|
|
4413
|
+
this.instanceName = `${klassName}:${instanceId} - ${new Error().stack?.split('\n')[2]}`;
|
|
4414
|
+
}
|
|
4415
|
+
};
|
|
4416
|
+
} else {
|
|
4417
|
+
// @ts-expect-error
|
|
4418
|
+
// eslint-disable-next-line
|
|
4419
|
+
const original = klass.prototype[methodName];
|
|
4420
|
+
const logName = `${klassName}.${methodName}`;
|
|
4421
|
+
|
|
4422
|
+
// @ts-expect-error
|
|
4423
|
+
klass.prototype[methodName] = function (...args) {
|
|
4424
|
+
// @ts-expect-error
|
|
4425
|
+
// eslint-disable-next-line
|
|
4426
|
+
globalThis.__WarpDriveMetricCountData[logName] = (globalThis.__WarpDriveMetricCountData[logName] || 0) + 1;
|
|
4427
|
+
// @ts-expect-error
|
|
4428
|
+
const {
|
|
4429
|
+
instanceName
|
|
4430
|
+
} = this;
|
|
4431
|
+
if (!instanceName) {
|
|
4432
|
+
// @ts-expect-error
|
|
4433
|
+
const instanceId = globalThis.__primitiveInstanceId++;
|
|
4434
|
+
// @ts-expect-error
|
|
4435
|
+
this.instanceName = `${klassName}.${methodName}:${instanceId} - ${new Error().stack?.split('\n')[2]}`;
|
|
4436
|
+
}
|
|
4437
|
+
const instanceLogName = `${logName} (${instanceName})`;
|
|
4438
|
+
// @ts-expect-error
|
|
4439
|
+
// eslint-disable-next-line
|
|
4440
|
+
globalThis.__WarpDriveMetricCountData[instanceLogName] =
|
|
4441
|
+
// @ts-expect-error
|
|
4442
|
+
// eslint-disable-next-line
|
|
4443
|
+
(globalThis.__WarpDriveMetricCountData[instanceLogName] || 0) + 1;
|
|
4444
|
+
// eslint-disable-next-line
|
|
4445
|
+
return original.apply(this, args);
|
|
4446
|
+
};
|
|
4447
|
+
}
|
|
4448
|
+
}
|
|
4449
|
+
interceptAndLog('Set', 'constructor');
|
|
4450
|
+
interceptAndLog('Set', 'add');
|
|
4451
|
+
interceptAndLog('Set', 'delete');
|
|
4452
|
+
interceptAndLog('Set', 'has');
|
|
4453
|
+
interceptAndLog('Set', 'set');
|
|
4454
|
+
interceptAndLog('Set', 'get');
|
|
4455
|
+
interceptAndLog('Map', 'constructor');
|
|
4456
|
+
interceptAndLog('Map', 'set');
|
|
4457
|
+
interceptAndLog('Map', 'delete');
|
|
4458
|
+
interceptAndLog('Map', 'has');
|
|
4459
|
+
interceptAndLog('Map', 'add');
|
|
4460
|
+
interceptAndLog('Map', 'get');
|
|
4461
|
+
interceptAndLog('WeakSet', 'constructor');
|
|
4462
|
+
interceptAndLog('WeakSet', 'add');
|
|
4463
|
+
interceptAndLog('WeakSet', 'delete');
|
|
4464
|
+
interceptAndLog('WeakSet', 'has');
|
|
4465
|
+
interceptAndLog('WeakSet', 'set');
|
|
4466
|
+
interceptAndLog('WeakSet', 'get');
|
|
4467
|
+
interceptAndLog('WeakMap', 'constructor');
|
|
4468
|
+
interceptAndLog('WeakMap', 'set');
|
|
4469
|
+
interceptAndLog('WeakMap', 'delete');
|
|
4470
|
+
interceptAndLog('WeakMap', 'has');
|
|
4471
|
+
interceptAndLog('WeakMap', 'add');
|
|
4472
|
+
interceptAndLog('WeakMap', 'get');
|
|
4473
|
+
}
|
|
4474
|
+
}
|
|
4475
|
+
}
|
|
4476
|
+
}
|
|
4477
|
+
|
|
4244
4478
|
// `AwaitedKeys` is needed here to resolve any promise types like `PromiseBelongsTo`.
|
|
4245
4479
|
|
|
4246
4480
|
/**
|
|
@@ -4623,22 +4857,26 @@ class Store extends BaseClass {
|
|
|
4623
4857
|
opts.disableTestWaiter = typeof requestConfig.disableTestWaiter === 'boolean' ? requestConfig.disableTestWaiter : true;
|
|
4624
4858
|
}
|
|
4625
4859
|
}
|
|
4626
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4860
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_REQUESTS)) {
|
|
4861
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_REQUESTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_REQUESTS) {
|
|
4862
|
+
let options;
|
|
4863
|
+
try {
|
|
4864
|
+
options = JSON.parse(JSON.stringify(requestConfig));
|
|
4865
|
+
} catch {
|
|
4866
|
+
options = requestConfig;
|
|
4867
|
+
}
|
|
4868
|
+
// eslint-disable-next-line no-console
|
|
4869
|
+
console.log(`request: [[START]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`, options);
|
|
4632
4870
|
}
|
|
4633
|
-
// eslint-disable-next-line no-console
|
|
4634
|
-
console.log(`request: [[START]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`, options);
|
|
4635
4871
|
}
|
|
4636
4872
|
const request = Object.assign({}, requestConfig, opts);
|
|
4637
4873
|
const future = this.requestManager.request(request);
|
|
4638
4874
|
future.onFinalize(() => {
|
|
4639
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
4640
|
-
|
|
4641
|
-
|
|
4875
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_REQUESTS)) {
|
|
4876
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_REQUESTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_REQUESTS) {
|
|
4877
|
+
// eslint-disable-next-line no-console
|
|
4878
|
+
console.log(`request: [[FINALIZE]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`);
|
|
4879
|
+
}
|
|
4642
4880
|
}
|
|
4643
4881
|
// skip flush for legacy belongsTo
|
|
4644
4882
|
if (requestConfig.op === 'findBelongsTo' && !requestConfig.url) {
|
|
@@ -4844,9 +5082,8 @@ class Store extends BaseClass {
|
|
|
4844
5082
|
This will cause the record to be destroyed and freed up for garbage collection.
|
|
4845
5083
|
Example
|
|
4846
5084
|
```javascript
|
|
4847
|
-
store.findRecord('post', '1')
|
|
4848
|
-
|
|
4849
|
-
});
|
|
5085
|
+
const { content: { data: post } } = await store.request(findRecord({ type: 'post', id: '1' }));
|
|
5086
|
+
store.unloadRecord(post);
|
|
4850
5087
|
```
|
|
4851
5088
|
@method unloadRecord
|
|
4852
5089
|
@public
|
|
@@ -6035,14 +6272,16 @@ class Store extends BaseClass {
|
|
|
6035
6272
|
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
6036
6273
|
assertDestroyingStore(this, '_push');
|
|
6037
6274
|
}
|
|
6038
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
|
|
6275
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_PAYLOADS)) {
|
|
6276
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_PAYLOADS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_PAYLOADS) {
|
|
6277
|
+
try {
|
|
6278
|
+
const data = JSON.parse(JSON.stringify(jsonApiDoc));
|
|
6279
|
+
// eslint-disable-next-line no-console
|
|
6280
|
+
console.log('EmberData | Payload - push', data);
|
|
6281
|
+
} catch {
|
|
6282
|
+
// eslint-disable-next-line no-console
|
|
6283
|
+
console.log('EmberData | Payload - push', jsonApiDoc);
|
|
6284
|
+
}
|
|
6046
6285
|
}
|
|
6047
6286
|
}
|
|
6048
6287
|
if (asyncFlush) {
|
|
@@ -6265,9 +6504,9 @@ function normalizeProperties(store, identifier, properties) {
|
|
|
6265
6504
|
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
6266
6505
|
assertRecordsPassedToHasMany(properties[prop]);
|
|
6267
6506
|
}
|
|
6268
|
-
properties[prop] = extractIdentifiersFromRecords(properties[prop]);
|
|
6507
|
+
properties[prop] = extractIdentifiersFromRecords$1(properties[prop]);
|
|
6269
6508
|
} else if (field.kind === 'belongsTo') {
|
|
6270
|
-
properties[prop] = extractIdentifierFromRecord(properties[prop]);
|
|
6509
|
+
properties[prop] = extractIdentifierFromRecord$1(properties[prop]);
|
|
6271
6510
|
}
|
|
6272
6511
|
}
|
|
6273
6512
|
}
|
|
@@ -6295,16 +6534,16 @@ function assertRecordsPassedToHasMany(records) {
|
|
|
6295
6534
|
});
|
|
6296
6535
|
}()) : {};
|
|
6297
6536
|
}
|
|
6298
|
-
function extractIdentifiersFromRecords(records) {
|
|
6299
|
-
return records.map(record => extractIdentifierFromRecord(record));
|
|
6537
|
+
function extractIdentifiersFromRecords$1(records) {
|
|
6538
|
+
return records.map(record => extractIdentifierFromRecord$1(record));
|
|
6300
6539
|
}
|
|
6301
|
-
function extractIdentifierFromRecord(recordOrPromiseRecord) {
|
|
6540
|
+
function extractIdentifierFromRecord$1(recordOrPromiseRecord) {
|
|
6302
6541
|
if (!recordOrPromiseRecord) {
|
|
6303
6542
|
return null;
|
|
6304
6543
|
}
|
|
6305
6544
|
const extract = recordIdentifierFor;
|
|
6306
6545
|
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_PROMISE_PROXIES)) {
|
|
6307
|
-
if (isPromiseRecord(recordOrPromiseRecord)) {
|
|
6546
|
+
if (isPromiseRecord$1(recordOrPromiseRecord)) {
|
|
6308
6547
|
const content = recordOrPromiseRecord.content;
|
|
6309
6548
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
6310
6549
|
if (!test) {
|
|
@@ -6325,7 +6564,7 @@ function extractIdentifierFromRecord(recordOrPromiseRecord) {
|
|
|
6325
6564
|
}
|
|
6326
6565
|
return extract(recordOrPromiseRecord);
|
|
6327
6566
|
}
|
|
6328
|
-
function isPromiseRecord(record) {
|
|
6567
|
+
function isPromiseRecord$1(record) {
|
|
6329
6568
|
return typeof record === 'object' && !!record && 'then' in record && typeof record.then === 'function';
|
|
6330
6569
|
}
|
|
6331
6570
|
|
|
@@ -6973,6 +7212,503 @@ function fetchContentAndHydrate(next, context, identifier, priority) {
|
|
|
6973
7212
|
/**
|
|
6974
7213
|
@module @ember-data/store
|
|
6975
7214
|
*/
|
|
7215
|
+
/**
|
|
7216
|
+
A `ManyArray` is a `MutableArray` that represents the contents of a has-many
|
|
7217
|
+
relationship.
|
|
7218
|
+
|
|
7219
|
+
The `ManyArray` is instantiated lazily the first time the relationship is
|
|
7220
|
+
requested.
|
|
7221
|
+
|
|
7222
|
+
This class is not intended to be directly instantiated by consuming applications.
|
|
7223
|
+
|
|
7224
|
+
### Inverses
|
|
7225
|
+
|
|
7226
|
+
Often, the relationships in Ember Data applications will have
|
|
7227
|
+
an inverse. For example, imagine the following models are
|
|
7228
|
+
defined:
|
|
7229
|
+
|
|
7230
|
+
```app/models/post.js
|
|
7231
|
+
import Model, { hasMany } from '@ember-data/model';
|
|
7232
|
+
|
|
7233
|
+
export default class PostModel extends Model {
|
|
7234
|
+
@hasMany('comment') comments;
|
|
7235
|
+
}
|
|
7236
|
+
```
|
|
7237
|
+
|
|
7238
|
+
```app/models/comment.js
|
|
7239
|
+
import Model, { belongsTo } from '@ember-data/model';
|
|
7240
|
+
|
|
7241
|
+
export default class CommentModel extends Model {
|
|
7242
|
+
@belongsTo('post') post;
|
|
7243
|
+
}
|
|
7244
|
+
```
|
|
7245
|
+
|
|
7246
|
+
If you created a new instance of `Post` and added
|
|
7247
|
+
a `Comment` record to its `comments` has-many
|
|
7248
|
+
relationship, you would expect the comment's `post`
|
|
7249
|
+
property to be set to the post that contained
|
|
7250
|
+
the has-many.
|
|
7251
|
+
|
|
7252
|
+
We call the record to which a relationship belongs-to the
|
|
7253
|
+
relationship's _owner_.
|
|
7254
|
+
|
|
7255
|
+
@class ManyArray
|
|
7256
|
+
@public
|
|
7257
|
+
*/
|
|
7258
|
+
class RelatedCollection extends IdentifierArray {
|
|
7259
|
+
/**
|
|
7260
|
+
The loading state of this array
|
|
7261
|
+
@property {Boolean} isLoaded
|
|
7262
|
+
@public
|
|
7263
|
+
*/
|
|
7264
|
+
|
|
7265
|
+
/**
|
|
7266
|
+
`true` if the relationship is polymorphic, `false` otherwise.
|
|
7267
|
+
@property {Boolean} isPolymorphic
|
|
7268
|
+
@private
|
|
7269
|
+
*/
|
|
7270
|
+
|
|
7271
|
+
/**
|
|
7272
|
+
Metadata associated with the request for async hasMany relationships.
|
|
7273
|
+
Example
|
|
7274
|
+
Given that the server returns the following JSON payload when fetching a
|
|
7275
|
+
hasMany relationship:
|
|
7276
|
+
```js
|
|
7277
|
+
{
|
|
7278
|
+
"comments": [{
|
|
7279
|
+
"id": 1,
|
|
7280
|
+
"comment": "This is the first comment",
|
|
7281
|
+
}, {
|
|
7282
|
+
// ...
|
|
7283
|
+
}],
|
|
7284
|
+
"meta": {
|
|
7285
|
+
"page": 1,
|
|
7286
|
+
"total": 5
|
|
7287
|
+
}
|
|
7288
|
+
}
|
|
7289
|
+
```
|
|
7290
|
+
You can then access the meta data via the `meta` property:
|
|
7291
|
+
```js
|
|
7292
|
+
let comments = await post.comments;
|
|
7293
|
+
let meta = comments.meta;
|
|
7294
|
+
// meta.page => 1
|
|
7295
|
+
// meta.total => 5
|
|
7296
|
+
```
|
|
7297
|
+
@property {Object | null} meta
|
|
7298
|
+
@public
|
|
7299
|
+
*/
|
|
7300
|
+
|
|
7301
|
+
/**
|
|
7302
|
+
* Retrieve the links for this relationship
|
|
7303
|
+
*
|
|
7304
|
+
@property {Object | null} links
|
|
7305
|
+
@public
|
|
7306
|
+
*/
|
|
7307
|
+
|
|
7308
|
+
constructor(options) {
|
|
7309
|
+
super(options);
|
|
7310
|
+
this.isLoaded = options.isLoaded || false;
|
|
7311
|
+
this.isAsync = options.isAsync || false;
|
|
7312
|
+
this.isPolymorphic = options.isPolymorphic || false;
|
|
7313
|
+
this.identifier = options.identifier;
|
|
7314
|
+
this.key = options.key;
|
|
7315
|
+
}
|
|
7316
|
+
[MUTATE](target, receiver, prop, args, _SIGNAL) {
|
|
7317
|
+
switch (prop) {
|
|
7318
|
+
case 'length 0':
|
|
7319
|
+
{
|
|
7320
|
+
Reflect.set(target, 'length', 0);
|
|
7321
|
+
mutateReplaceRelatedRecords(this, [], _SIGNAL);
|
|
7322
|
+
return true;
|
|
7323
|
+
}
|
|
7324
|
+
case 'replace cell':
|
|
7325
|
+
{
|
|
7326
|
+
const [index, prior, value] = args;
|
|
7327
|
+
target[index] = value;
|
|
7328
|
+
mutateReplaceRelatedRecord(this, {
|
|
7329
|
+
value,
|
|
7330
|
+
prior,
|
|
7331
|
+
index
|
|
7332
|
+
}, _SIGNAL);
|
|
7333
|
+
return true;
|
|
7334
|
+
}
|
|
7335
|
+
case 'push':
|
|
7336
|
+
{
|
|
7337
|
+
const newValues = extractIdentifiersFromRecords(args);
|
|
7338
|
+
assertNoDuplicates(this, target, currentState => currentState.push(...newValues), `Cannot push duplicates to a hasMany's state.`);
|
|
7339
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
7340
|
+
// dedupe
|
|
7341
|
+
const seen = new Set(target);
|
|
7342
|
+
const unique = new Set();
|
|
7343
|
+
args.forEach(item => {
|
|
7344
|
+
const identifier = recordIdentifierFor(item);
|
|
7345
|
+
if (!seen.has(identifier)) {
|
|
7346
|
+
seen.add(identifier);
|
|
7347
|
+
unique.add(item);
|
|
7348
|
+
}
|
|
7349
|
+
});
|
|
7350
|
+
const newArgs = Array.from(unique);
|
|
7351
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
7352
|
+
if (newArgs.length) {
|
|
7353
|
+
mutateAddToRelatedRecords(this, {
|
|
7354
|
+
value: extractIdentifiersFromRecords(newArgs)
|
|
7355
|
+
}, _SIGNAL);
|
|
7356
|
+
}
|
|
7357
|
+
return result;
|
|
7358
|
+
}
|
|
7359
|
+
|
|
7360
|
+
// else, no dedupe, error on duplicates
|
|
7361
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
7362
|
+
if (newValues.length) {
|
|
7363
|
+
mutateAddToRelatedRecords(this, {
|
|
7364
|
+
value: newValues
|
|
7365
|
+
}, _SIGNAL);
|
|
7366
|
+
}
|
|
7367
|
+
return result;
|
|
7368
|
+
}
|
|
7369
|
+
case 'pop':
|
|
7370
|
+
{
|
|
7371
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
7372
|
+
if (result) {
|
|
7373
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
7374
|
+
value: recordIdentifierFor(result)
|
|
7375
|
+
}, _SIGNAL);
|
|
7376
|
+
}
|
|
7377
|
+
return result;
|
|
7378
|
+
}
|
|
7379
|
+
case 'unshift':
|
|
7380
|
+
{
|
|
7381
|
+
const newValues = extractIdentifiersFromRecords(args);
|
|
7382
|
+
assertNoDuplicates(this, target, currentState => currentState.unshift(...newValues), `Cannot unshift duplicates to a hasMany's state.`);
|
|
7383
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
7384
|
+
// dedupe
|
|
7385
|
+
const seen = new Set(target);
|
|
7386
|
+
const unique = new Set();
|
|
7387
|
+
args.forEach(item => {
|
|
7388
|
+
const identifier = recordIdentifierFor(item);
|
|
7389
|
+
if (!seen.has(identifier)) {
|
|
7390
|
+
seen.add(identifier);
|
|
7391
|
+
unique.add(item);
|
|
7392
|
+
}
|
|
7393
|
+
});
|
|
7394
|
+
const newArgs = Array.from(unique);
|
|
7395
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
7396
|
+
if (newArgs.length) {
|
|
7397
|
+
mutateAddToRelatedRecords(this, {
|
|
7398
|
+
value: extractIdentifiersFromRecords(newArgs),
|
|
7399
|
+
index: 0
|
|
7400
|
+
}, _SIGNAL);
|
|
7401
|
+
}
|
|
7402
|
+
return result;
|
|
7403
|
+
}
|
|
7404
|
+
|
|
7405
|
+
// else, no dedupe, error on duplicates
|
|
7406
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
7407
|
+
if (newValues.length) {
|
|
7408
|
+
mutateAddToRelatedRecords(this, {
|
|
7409
|
+
value: newValues,
|
|
7410
|
+
index: 0
|
|
7411
|
+
}, _SIGNAL);
|
|
7412
|
+
}
|
|
7413
|
+
return result;
|
|
7414
|
+
}
|
|
7415
|
+
case 'shift':
|
|
7416
|
+
{
|
|
7417
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
7418
|
+
if (result) {
|
|
7419
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
7420
|
+
value: recordIdentifierFor(result),
|
|
7421
|
+
index: 0
|
|
7422
|
+
}, _SIGNAL);
|
|
7423
|
+
}
|
|
7424
|
+
return result;
|
|
7425
|
+
}
|
|
7426
|
+
case 'sort':
|
|
7427
|
+
{
|
|
7428
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
7429
|
+
mutateSortRelatedRecords(this, result.map(recordIdentifierFor), _SIGNAL);
|
|
7430
|
+
return result;
|
|
7431
|
+
}
|
|
7432
|
+
case 'splice':
|
|
7433
|
+
{
|
|
7434
|
+
const [start, deleteCount, ...adds] = args;
|
|
7435
|
+
|
|
7436
|
+
// detect a full replace
|
|
7437
|
+
if (start === 0 && deleteCount === this[SOURCE].length) {
|
|
7438
|
+
const newValues = extractIdentifiersFromRecords(adds);
|
|
7439
|
+
assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot replace a hasMany's state with a new state that contains duplicates.`);
|
|
7440
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
7441
|
+
// dedupe
|
|
7442
|
+
const current = new Set(adds);
|
|
7443
|
+
const unique = Array.from(current);
|
|
7444
|
+
const uniqueIdentifiers = Array.from(new Set(newValues));
|
|
7445
|
+
const newArgs = [start, deleteCount].concat(unique);
|
|
7446
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
7447
|
+
mutateReplaceRelatedRecords(this, uniqueIdentifiers, _SIGNAL);
|
|
7448
|
+
return result;
|
|
7449
|
+
}
|
|
7450
|
+
|
|
7451
|
+
// else, no dedupe, error on duplicates
|
|
7452
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
7453
|
+
mutateReplaceRelatedRecords(this, newValues, _SIGNAL);
|
|
7454
|
+
return result;
|
|
7455
|
+
}
|
|
7456
|
+
const newValues = extractIdentifiersFromRecords(adds);
|
|
7457
|
+
assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot splice a hasMany's state with a new state that contains duplicates.`);
|
|
7458
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
7459
|
+
// dedupe
|
|
7460
|
+
const currentState = target.slice();
|
|
7461
|
+
currentState.splice(start, deleteCount);
|
|
7462
|
+
const seen = new Set(currentState);
|
|
7463
|
+
const unique = [];
|
|
7464
|
+
adds.forEach(item => {
|
|
7465
|
+
const identifier = recordIdentifierFor(item);
|
|
7466
|
+
if (!seen.has(identifier)) {
|
|
7467
|
+
seen.add(identifier);
|
|
7468
|
+
unique.push(item);
|
|
7469
|
+
}
|
|
7470
|
+
});
|
|
7471
|
+
const newArgs = [start, deleteCount, ...unique];
|
|
7472
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
7473
|
+
if (deleteCount > 0) {
|
|
7474
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
7475
|
+
value: result.map(recordIdentifierFor),
|
|
7476
|
+
index: start
|
|
7477
|
+
}, _SIGNAL);
|
|
7478
|
+
}
|
|
7479
|
+
if (unique.length > 0) {
|
|
7480
|
+
mutateAddToRelatedRecords(this, {
|
|
7481
|
+
value: extractIdentifiersFromRecords(unique),
|
|
7482
|
+
index: start
|
|
7483
|
+
}, _SIGNAL);
|
|
7484
|
+
}
|
|
7485
|
+
return result;
|
|
7486
|
+
}
|
|
7487
|
+
|
|
7488
|
+
// else, no dedupe, error on duplicates
|
|
7489
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
7490
|
+
if (deleteCount > 0) {
|
|
7491
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
7492
|
+
value: result.map(recordIdentifierFor),
|
|
7493
|
+
index: start
|
|
7494
|
+
}, _SIGNAL);
|
|
7495
|
+
}
|
|
7496
|
+
if (newValues.length > 0) {
|
|
7497
|
+
mutateAddToRelatedRecords(this, {
|
|
7498
|
+
value: newValues,
|
|
7499
|
+
index: start
|
|
7500
|
+
}, _SIGNAL);
|
|
7501
|
+
}
|
|
7502
|
+
return result;
|
|
7503
|
+
}
|
|
7504
|
+
default:
|
|
7505
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
7506
|
+
{
|
|
7507
|
+
throw new Error(`unable to convert ${prop} into a transaction that updates the cache state for this record array`);
|
|
7508
|
+
}
|
|
7509
|
+
})() : {};
|
|
7510
|
+
}
|
|
7511
|
+
}
|
|
7512
|
+
notify() {
|
|
7513
|
+
const signal = this[ARRAY_SIGNAL];
|
|
7514
|
+
signal.shouldReset = true;
|
|
7515
|
+
notifyArray(this);
|
|
7516
|
+
}
|
|
7517
|
+
|
|
7518
|
+
/**
|
|
7519
|
+
Reloads all of the records in the manyArray. If the manyArray
|
|
7520
|
+
holds a relationship that was originally fetched using a links url
|
|
7521
|
+
EmberData will revisit the original links url to repopulate the
|
|
7522
|
+
relationship.
|
|
7523
|
+
If the ManyArray holds the result of a `store.query()` reload will
|
|
7524
|
+
re-run the original query.
|
|
7525
|
+
Example
|
|
7526
|
+
```javascript
|
|
7527
|
+
let user = store.peekRecord('user', '1')
|
|
7528
|
+
await login(user);
|
|
7529
|
+
let permissions = await user.permissions;
|
|
7530
|
+
await permissions.reload();
|
|
7531
|
+
```
|
|
7532
|
+
@method reload
|
|
7533
|
+
@public
|
|
7534
|
+
*/
|
|
7535
|
+
reload(options) {
|
|
7536
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
7537
|
+
if (!test) {
|
|
7538
|
+
throw new Error(`Expected the manager for ManyArray to implement reloadHasMany`);
|
|
7539
|
+
}
|
|
7540
|
+
})(typeof this._manager.reloadHasMany === 'function') : {};
|
|
7541
|
+
// TODO this is odd, we don't ask the store for anything else like this?
|
|
7542
|
+
return this._manager.reloadHasMany(this.key, options);
|
|
7543
|
+
}
|
|
7544
|
+
|
|
7545
|
+
/**
|
|
7546
|
+
Saves all of the records in the `ManyArray`.
|
|
7547
|
+
Note: this API can only be used in legacy mode with a configured Adapter.
|
|
7548
|
+
Example
|
|
7549
|
+
```javascript
|
|
7550
|
+
const { content: { data: inbox } } = await store.request(findRecord({ type: 'inbox', id: '1' }));
|
|
7551
|
+
let messages = await inbox.messages;
|
|
7552
|
+
messages.forEach((message) => {
|
|
7553
|
+
message.isRead = true;
|
|
7554
|
+
});
|
|
7555
|
+
messages.save();
|
|
7556
|
+
```
|
|
7557
|
+
@method save
|
|
7558
|
+
@public
|
|
7559
|
+
@return {PromiseArray} promise
|
|
7560
|
+
*/
|
|
7561
|
+
|
|
7562
|
+
/**
|
|
7563
|
+
Create a child record within the owner
|
|
7564
|
+
@method createRecord
|
|
7565
|
+
@public
|
|
7566
|
+
@param {Object} hash
|
|
7567
|
+
@return {Model} record
|
|
7568
|
+
*/
|
|
7569
|
+
createRecord(hash) {
|
|
7570
|
+
const {
|
|
7571
|
+
store
|
|
7572
|
+
} = this;
|
|
7573
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
7574
|
+
if (!test) {
|
|
7575
|
+
throw new Error(`Expected modelName to be set`);
|
|
7576
|
+
}
|
|
7577
|
+
})(this.modelName) : {};
|
|
7578
|
+
const record = store.createRecord(this.modelName, hash);
|
|
7579
|
+
this.push(record);
|
|
7580
|
+
return record;
|
|
7581
|
+
}
|
|
7582
|
+
destroy() {
|
|
7583
|
+
super.destroy(false);
|
|
7584
|
+
}
|
|
7585
|
+
}
|
|
7586
|
+
RelatedCollection.prototype.isAsync = false;
|
|
7587
|
+
RelatedCollection.prototype.isPolymorphic = false;
|
|
7588
|
+
RelatedCollection.prototype.identifier = null;
|
|
7589
|
+
RelatedCollection.prototype.cache = null;
|
|
7590
|
+
RelatedCollection.prototype._inverseIsAsync = false;
|
|
7591
|
+
RelatedCollection.prototype.key = '';
|
|
7592
|
+
RelatedCollection.prototype.DEPRECATED_CLASS_NAME = 'ManyArray';
|
|
7593
|
+
function assertRecordPassedToHasMany(record) {
|
|
7594
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
7595
|
+
if (!test) {
|
|
7596
|
+
throw new Error(`All elements of a hasMany relationship must be instances of Model, you passed ${typeof record}`);
|
|
7597
|
+
}
|
|
7598
|
+
})(function () {
|
|
7599
|
+
try {
|
|
7600
|
+
recordIdentifierFor(record);
|
|
7601
|
+
return true;
|
|
7602
|
+
} catch {
|
|
7603
|
+
return false;
|
|
7604
|
+
}
|
|
7605
|
+
}()) : {};
|
|
7606
|
+
}
|
|
7607
|
+
function extractIdentifiersFromRecords(records) {
|
|
7608
|
+
return records.map(extractIdentifierFromRecord);
|
|
7609
|
+
}
|
|
7610
|
+
function extractIdentifierFromRecord(recordOrPromiseRecord) {
|
|
7611
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_PROMISE_PROXIES)) {
|
|
7612
|
+
if (isPromiseRecord(recordOrPromiseRecord)) {
|
|
7613
|
+
const content = recordOrPromiseRecord.content;
|
|
7614
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
7615
|
+
if (!test) {
|
|
7616
|
+
throw new Error('You passed in a promise that did not originate from an EmberData relationship. You can only pass promises that come from a belongsTo relationship.');
|
|
7617
|
+
}
|
|
7618
|
+
})(content !== undefined && content !== null) : {};
|
|
7619
|
+
deprecate(`You passed in a PromiseProxy to a Relationship API that now expects a resolved value. await the value before setting it.`, false, {
|
|
7620
|
+
id: 'ember-data:deprecate-promise-proxies',
|
|
7621
|
+
until: '5.0',
|
|
7622
|
+
since: {
|
|
7623
|
+
enabled: '4.7',
|
|
7624
|
+
available: '4.7'
|
|
7625
|
+
},
|
|
7626
|
+
for: 'ember-data'
|
|
7627
|
+
});
|
|
7628
|
+
assertRecordPassedToHasMany(content);
|
|
7629
|
+
return recordIdentifierFor(content);
|
|
7630
|
+
}
|
|
7631
|
+
}
|
|
7632
|
+
assertRecordPassedToHasMany(recordOrPromiseRecord);
|
|
7633
|
+
return recordIdentifierFor(recordOrPromiseRecord);
|
|
7634
|
+
}
|
|
7635
|
+
function isPromiseRecord(record) {
|
|
7636
|
+
return Boolean(typeof record === 'object' && record && 'then' in record);
|
|
7637
|
+
}
|
|
7638
|
+
function assertNoDuplicates(collection, target, callback, reason) {
|
|
7639
|
+
const state = target.slice();
|
|
7640
|
+
callback(state);
|
|
7641
|
+
if (state.length !== new Set(state).size) {
|
|
7642
|
+
const duplicates = state.filter((currentValue, currentIndex) => state.indexOf(currentValue) !== currentIndex);
|
|
7643
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
7644
|
+
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- ')}`, /* inline-macro-config */getGlobalConfig().WarpDrive.deprecations.DISABLE_6X_DEPRECATIONS, {
|
|
7645
|
+
id: 'ember-data:deprecate-many-array-duplicates',
|
|
7646
|
+
for: 'ember-data',
|
|
7647
|
+
until: '6.0',
|
|
7648
|
+
since: {
|
|
7649
|
+
enabled: '5.3',
|
|
7650
|
+
available: '4.13'
|
|
7651
|
+
}
|
|
7652
|
+
});
|
|
7653
|
+
} else {
|
|
7654
|
+
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- ')}`);
|
|
7655
|
+
}
|
|
7656
|
+
}
|
|
7657
|
+
}
|
|
7658
|
+
function mutateAddToRelatedRecords(collection, operationInfo, _SIGNAL) {
|
|
7659
|
+
mutate(collection, {
|
|
7660
|
+
op: 'addToRelatedRecords',
|
|
7661
|
+
record: collection.identifier,
|
|
7662
|
+
field: collection.key,
|
|
7663
|
+
...operationInfo
|
|
7664
|
+
}, _SIGNAL);
|
|
7665
|
+
}
|
|
7666
|
+
function mutateRemoveFromRelatedRecords(collection, operationInfo, _SIGNAL) {
|
|
7667
|
+
mutate(collection, {
|
|
7668
|
+
op: 'removeFromRelatedRecords',
|
|
7669
|
+
record: collection.identifier,
|
|
7670
|
+
field: collection.key,
|
|
7671
|
+
...operationInfo
|
|
7672
|
+
}, _SIGNAL);
|
|
7673
|
+
}
|
|
7674
|
+
function mutateReplaceRelatedRecord(collection, operationInfo, _SIGNAL) {
|
|
7675
|
+
mutate(collection, {
|
|
7676
|
+
op: 'replaceRelatedRecord',
|
|
7677
|
+
record: collection.identifier,
|
|
7678
|
+
field: collection.key,
|
|
7679
|
+
...operationInfo
|
|
7680
|
+
}, _SIGNAL);
|
|
7681
|
+
}
|
|
7682
|
+
function mutateReplaceRelatedRecords(collection, value, _SIGNAL) {
|
|
7683
|
+
mutate(collection, {
|
|
7684
|
+
op: 'replaceRelatedRecords',
|
|
7685
|
+
record: collection.identifier,
|
|
7686
|
+
field: collection.key,
|
|
7687
|
+
value
|
|
7688
|
+
}, _SIGNAL);
|
|
7689
|
+
}
|
|
7690
|
+
function mutateSortRelatedRecords(collection, value, _SIGNAL) {
|
|
7691
|
+
mutate(collection, {
|
|
7692
|
+
op: 'sortRelatedRecords',
|
|
7693
|
+
record: collection.identifier,
|
|
7694
|
+
field: collection.key,
|
|
7695
|
+
value
|
|
7696
|
+
}, _SIGNAL);
|
|
7697
|
+
}
|
|
7698
|
+
function mutate(collection, mutation, _SIGNAL) {
|
|
7699
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
7700
|
+
if (!test) {
|
|
7701
|
+
throw new Error(`Expected the manager for ManyArray to implement mutate`);
|
|
7702
|
+
}
|
|
7703
|
+
})(typeof collection._manager.mutate === 'function') : {};
|
|
7704
|
+
collection._manager.mutate(mutation);
|
|
7705
|
+
addToTransaction(_SIGNAL);
|
|
7706
|
+
}
|
|
7707
|
+
|
|
7708
|
+
/**
|
|
7709
|
+
@module @ember-data/store
|
|
7710
|
+
*/
|
|
7711
|
+
|
|
6976
7712
|
/**
|
|
6977
7713
|
This method normalizes a modelName into the format EmberData uses
|
|
6978
7714
|
internally by dasherizing it.
|
|
@@ -7000,4 +7736,4 @@ function normalizeModelName(modelName) {
|
|
|
7000
7736
|
}
|
|
7001
7737
|
assert(`normalizeModelName support has been removed`);
|
|
7002
7738
|
}
|
|
7003
|
-
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, notifyArray as k, SOURCE as l, fastPush as m, normalizeModelName as n, removeRecordDataFor as o, peekCache as p, setRecordIdentifier as q, recordIdentifierFor as r, storeFor as s, StoreMap as t, setCacheFor as u,
|
|
7739
|
+
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, notifyArray as k, SOURCE as l, fastPush as m, normalizeModelName as n, removeRecordDataFor as o, peekCache as p, setRecordIdentifier as q, recordIdentifierFor as r, storeFor as s, StoreMap as t, setCacheFor as u, RelatedCollection as v, log as w, logGroup as x };
|