@ember-data/store 4.13.0-alpha.3 → 4.13.0-alpha.5
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 +5 -8
- package/dist/{-private-Cy8UqsrK.js → -private-ki-omnNZ.js} +823 -131
- package/dist/-private-ki-omnNZ.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 +32 -42
- package/unstable-preview-types/-private/cache-handler/handler.d.ts +0 -2
- package/unstable-preview-types/-private/cache-handler/handler.d.ts.map +1 -1
- package/unstable-preview-types/-private/caches/identifier-cache.d.ts.map +1 -1
- package/unstable-preview-types/-private/caches/instance-cache.d.ts.map +1 -1
- package/unstable-preview-types/-private/debug/utils.d.ts +9 -0
- package/unstable-preview-types/-private/debug/utils.d.ts.map +1 -0
- package/unstable-preview-types/-private/managers/cache-capabilities-manager.d.ts +3 -3
- package/unstable-preview-types/-private/managers/cache-capabilities-manager.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 +3 -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 +64 -9
- package/unstable-preview-types/-private/store-service.d.ts.map +1 -1
- package/unstable-preview-types/-private.d.ts +2 -0
- package/unstable-preview-types/-private.d.ts.map +1 -1
- package/unstable-preview-types/-types/q/cache-capabilities-manager.d.ts +4 -4
- package/unstable-preview-types/-types/q/cache-capabilities-manager.d.ts.map +1 -1
- package/unstable-preview-types/index.d.ts +24 -25
- package/unstable-preview-types/index.d.ts.map +1 -1
- package/dist/-private-Cy8UqsrK.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
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
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
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { setLogging, getRuntimeConfig } from '@warp-drive/build-config/runtime';
|
|
5
|
+
import { EnableHydration, SkipCache } from '@warp-drive/core-types/request';
|
|
6
|
+
import { getOrSetGlobal, peekTransient, setTransient } from '@warp-drive/core-types/-private';
|
|
6
7
|
import { CACHE_OWNER, DEBUG_STALE_CACHE_OWNER, DEBUG_CLIENT_ORIGINATED, DEBUG_IDENTIFIER_BUCKET } 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';
|
|
@@ -136,10 +137,9 @@ function hasType(resource) {
|
|
|
136
137
|
/**
|
|
137
138
|
@module @ember-data/store
|
|
138
139
|
*/
|
|
139
|
-
const IDENTIFIERS = getOrSetGlobal('IDENTIFIERS', new Set());
|
|
140
140
|
const DOCUMENTS = getOrSetGlobal('DOCUMENTS', new Set());
|
|
141
141
|
function isStableIdentifier(identifier) {
|
|
142
|
-
return identifier[CACHE_OWNER] !== undefined
|
|
142
|
+
return identifier[CACHE_OWNER] !== undefined;
|
|
143
143
|
}
|
|
144
144
|
function isDocumentIdentifier(identifier) {
|
|
145
145
|
return DOCUMENTS.has(identifier);
|
|
@@ -317,9 +317,11 @@ class IdentifierCache {
|
|
|
317
317
|
*/
|
|
318
318
|
|
|
319
319
|
_getRecordIdentifier(resource, shouldGenerate) {
|
|
320
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
321
|
-
|
|
322
|
-
|
|
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
|
+
}
|
|
323
325
|
}
|
|
324
326
|
// short circuit if we're already the stable version
|
|
325
327
|
if (isStableIdentifier(resource)) {
|
|
@@ -329,33 +331,41 @@ class IdentifierCache {
|
|
|
329
331
|
throw new Error(`The supplied identifier ${JSON.stringify(resource)} does not belong to this store instance`);
|
|
330
332
|
}
|
|
331
333
|
}
|
|
332
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
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
|
+
}
|
|
337
341
|
}
|
|
338
342
|
return resource;
|
|
339
343
|
}
|
|
340
344
|
|
|
341
345
|
// the resource is unknown, ask the application to identify this data for us
|
|
342
346
|
const lid = this._generate(resource, 'record');
|
|
343
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
344
|
-
|
|
345
|
-
|
|
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
|
+
}
|
|
346
352
|
}
|
|
347
353
|
let identifier = /*#__NOINLINE__*/getIdentifierFromLid(this._cache, lid, resource);
|
|
348
354
|
if (identifier !== null) {
|
|
349
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
350
|
-
|
|
351
|
-
|
|
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
|
+
}
|
|
352
360
|
}
|
|
353
361
|
return identifier;
|
|
354
362
|
}
|
|
355
363
|
if (shouldGenerate === 0) {
|
|
356
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
357
|
-
|
|
358
|
-
|
|
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
|
+
}
|
|
359
369
|
}
|
|
360
370
|
return;
|
|
361
371
|
}
|
|
@@ -373,9 +383,11 @@ class IdentifierCache {
|
|
|
373
383
|
identifier = /*#__NOINLINE__*/makeStableRecordIdentifier(keyInfo, 'record', false);
|
|
374
384
|
}
|
|
375
385
|
addResourceToCache(this._cache, identifier);
|
|
376
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
377
|
-
|
|
378
|
-
|
|
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
|
+
}
|
|
379
391
|
}
|
|
380
392
|
return identifier;
|
|
381
393
|
}
|
|
@@ -469,9 +481,11 @@ class IdentifierCache {
|
|
|
469
481
|
|
|
470
482
|
/*#__NOINLINE__*/
|
|
471
483
|
addResourceToCache(this._cache, identifier);
|
|
472
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
473
|
-
|
|
474
|
-
|
|
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
|
+
}
|
|
475
489
|
}
|
|
476
490
|
return identifier;
|
|
477
491
|
}
|
|
@@ -518,9 +532,11 @@ class IdentifierCache {
|
|
|
518
532
|
if (hadLid) {
|
|
519
533
|
data.lid = identifier.lid;
|
|
520
534
|
}
|
|
521
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
522
|
-
|
|
523
|
-
|
|
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
|
+
}
|
|
524
540
|
}
|
|
525
541
|
}
|
|
526
542
|
const id = identifier.id;
|
|
@@ -530,9 +546,11 @@ class IdentifierCache {
|
|
|
530
546
|
|
|
531
547
|
// add to our own secondary lookup table
|
|
532
548
|
if (id !== newId && newId !== null) {
|
|
533
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
534
|
-
|
|
535
|
-
|
|
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
|
+
}
|
|
536
554
|
}
|
|
537
555
|
const typeSet = this._cache.resourcesByType[identifier.type];
|
|
538
556
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
@@ -544,9 +562,11 @@ class IdentifierCache {
|
|
|
544
562
|
if (id !== null) {
|
|
545
563
|
typeSet.id.delete(id);
|
|
546
564
|
}
|
|
547
|
-
} else if (macroCondition(getGlobalConfig().WarpDrive.
|
|
548
|
-
|
|
549
|
-
|
|
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
|
+
}
|
|
550
570
|
}
|
|
551
571
|
return identifier;
|
|
552
572
|
}
|
|
@@ -628,11 +648,12 @@ class IdentifierCache {
|
|
|
628
648
|
identifier[DEBUG_STALE_CACHE_OWNER] = identifier[CACHE_OWNER];
|
|
629
649
|
}
|
|
630
650
|
identifier[CACHE_OWNER] = undefined;
|
|
631
|
-
IDENTIFIERS.delete(identifier);
|
|
632
651
|
this._forget(identifier, 'record');
|
|
633
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
634
|
-
|
|
635
|
-
|
|
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
|
+
}
|
|
636
657
|
}
|
|
637
658
|
}
|
|
638
659
|
destroy() {
|
|
@@ -644,7 +665,6 @@ class IdentifierCache {
|
|
|
644
665
|
}
|
|
645
666
|
}
|
|
646
667
|
function makeStableRecordIdentifier(recordIdentifier, bucket, clientOriginated) {
|
|
647
|
-
IDENTIFIERS.add(recordIdentifier);
|
|
648
668
|
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
649
669
|
// we enforce immutability in dev
|
|
650
670
|
// but preserve our ability to do controlled updates to the reference
|
|
@@ -699,7 +719,6 @@ function makeStableRecordIdentifier(recordIdentifier, bucket, clientOriginated)
|
|
|
699
719
|
});
|
|
700
720
|
wrapper[DEBUG_CLIENT_ORIGINATED] = clientOriginated;
|
|
701
721
|
wrapper[DEBUG_IDENTIFIER_BUCKET] = bucket;
|
|
702
|
-
IDENTIFIERS.add(wrapper);
|
|
703
722
|
DEBUG_MAP.set(wrapper, recordIdentifier);
|
|
704
723
|
wrapper = freeze(wrapper);
|
|
705
724
|
return wrapper;
|
|
@@ -782,9 +801,11 @@ function detectMerge(cache, keyInfo, identifier, data) {
|
|
|
782
801
|
}
|
|
783
802
|
function getIdentifierFromLid(cache, lid, resource) {
|
|
784
803
|
const identifier = cache.resources.get(lid);
|
|
785
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
786
|
-
|
|
787
|
-
|
|
804
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
805
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
806
|
+
// eslint-disable-next-line no-console
|
|
807
|
+
console.log(`Identifiers: cache ${identifier ? 'HIT' : 'MISS'} - Non-Stable ${lid}`, resource);
|
|
808
|
+
}
|
|
788
809
|
}
|
|
789
810
|
return identifier || null;
|
|
790
811
|
}
|
|
@@ -803,6 +824,87 @@ function addResourceToCache(cache, identifier) {
|
|
|
803
824
|
typeSet.id.set(identifier.id, identifier);
|
|
804
825
|
}
|
|
805
826
|
}
|
|
827
|
+
const TEXT_COLORS = {
|
|
828
|
+
TEXT: 'inherit',
|
|
829
|
+
notify: ['white', 'white', 'inherit', 'magenta', 'inherit'],
|
|
830
|
+
'reactive-ui': ['white', 'white', 'inherit', 'magenta', 'inherit'],
|
|
831
|
+
graph: ['white', 'white', 'inherit', 'magenta', 'inherit'],
|
|
832
|
+
request: ['white', 'white', 'inherit', 'magenta', 'inherit'],
|
|
833
|
+
cache: ['white', 'white', 'inherit', 'magenta', 'inherit']
|
|
834
|
+
};
|
|
835
|
+
const BG_COLORS = {
|
|
836
|
+
TEXT: 'transparent',
|
|
837
|
+
notify: ['dimgray', 'cadetblue', 'transparent', 'transparent', 'transparent'],
|
|
838
|
+
'reactive-ui': ['dimgray', 'cadetblue', 'transparent', 'transparent', 'transparent'],
|
|
839
|
+
graph: ['dimgray', 'cadetblue', 'transparent', 'transparent', 'transparent'],
|
|
840
|
+
request: ['dimgray', 'cadetblue', 'transparent', 'transparent', 'transparent'],
|
|
841
|
+
cache: ['dimgray', 'cadetblue', 'transparent', 'transparent', 'transparent']
|
|
842
|
+
};
|
|
843
|
+
const NOTIFY_BORDER = {
|
|
844
|
+
TEXT: 0,
|
|
845
|
+
notify: [3, 2, 0, 0, 0],
|
|
846
|
+
'reactive-ui': [3, 2, 0, 0, 0],
|
|
847
|
+
graph: [3, 2, 0, 0, 0],
|
|
848
|
+
request: [3, 2, 0, 0, 0],
|
|
849
|
+
cache: [3, 2, 0, 0, 0]
|
|
850
|
+
};
|
|
851
|
+
const LIGHT_DARK_ALT = {
|
|
852
|
+
lightgreen: 'green',
|
|
853
|
+
green: 'lightgreen'
|
|
854
|
+
};
|
|
855
|
+
function badge(isLight, color, bgColor, border) {
|
|
856
|
+
return [`color: ${correctColor(isLight, color)}; background-color: ${correctColor(isLight, bgColor)}; padding: ${border}px ${2 * border}px; border-radius: ${border}px;`, `color: ${TEXT_COLORS.TEXT}; background-color: ${BG_COLORS.TEXT};`];
|
|
857
|
+
}
|
|
858
|
+
function colorForBucket(isLight, scope, bucket) {
|
|
859
|
+
if (scope === 'notify') {
|
|
860
|
+
return bucket === 'added' ? badge(isLight, 'lightgreen', 'transparent', 0) : bucket === 'removed' ? badge(isLight, 'red', 'transparent', 0) : badge(isLight, TEXT_COLORS[scope][2], BG_COLORS[scope][2], NOTIFY_BORDER[scope][2]);
|
|
861
|
+
}
|
|
862
|
+
if (scope === 'reactive-ui') {
|
|
863
|
+
return bucket === 'created' ? badge(isLight, 'lightgreen', 'transparent', 0) : bucket === 'disconnected' ? badge(isLight, 'red', 'transparent', 0) : badge(isLight, TEXT_COLORS[scope][2], BG_COLORS[scope][2], NOTIFY_BORDER[scope][2]);
|
|
864
|
+
}
|
|
865
|
+
if (scope === 'cache') {
|
|
866
|
+
return bucket === 'inserted' ? badge(isLight, 'lightgreen', 'transparent', 0) : bucket === 'removed' ? badge(isLight, 'red', 'transparent', 0) : badge(isLight, TEXT_COLORS[scope][2], BG_COLORS[scope][2], NOTIFY_BORDER[scope][2]);
|
|
867
|
+
}
|
|
868
|
+
return badge(isLight, TEXT_COLORS[scope][3], BG_COLORS[scope][3], NOTIFY_BORDER[scope][3]);
|
|
869
|
+
}
|
|
870
|
+
function logGroup(scope, prefix, subScop1, subScop2, subScop3, subScop4) {
|
|
871
|
+
// eslint-disable-next-line no-console
|
|
872
|
+
console.groupCollapsed(..._log(scope, prefix, subScop1, subScop2, subScop3, subScop4));
|
|
873
|
+
}
|
|
874
|
+
function log(scope, prefix, subScop1, subScop2, subScop3, subScop4) {
|
|
875
|
+
// eslint-disable-next-line no-console
|
|
876
|
+
console.log(..._log(scope, prefix, subScop1, subScop2, subScop3, subScop4));
|
|
877
|
+
}
|
|
878
|
+
function correctColor(isLight, color) {
|
|
879
|
+
if (!isLight) {
|
|
880
|
+
return color;
|
|
881
|
+
}
|
|
882
|
+
return color in LIGHT_DARK_ALT ? LIGHT_DARK_ALT[color] : color;
|
|
883
|
+
}
|
|
884
|
+
function isLightMode() {
|
|
885
|
+
if (window?.matchMedia?.('(prefers-color-scheme: light)').matches) {
|
|
886
|
+
return true;
|
|
887
|
+
}
|
|
888
|
+
return false;
|
|
889
|
+
}
|
|
890
|
+
function _log(scope, prefix, subScop1, subScop2, subScop3, subScop4) {
|
|
891
|
+
const isLight = isLightMode();
|
|
892
|
+
switch (scope) {
|
|
893
|
+
case 'reactive-ui':
|
|
894
|
+
case 'notify':
|
|
895
|
+
{
|
|
896
|
+
const scopePath = prefix ? `[${prefix}] ${scope}` : scope;
|
|
897
|
+
const path = subScop4 ? `${subScop3}.${subScop4}` : subScop3;
|
|
898
|
+
return [`%c@warp%c-%cdrive%c %c${scopePath}%c %c${subScop1}%c %c${subScop2}%c %c${path}%c`, ...badge(isLight, 'lightgreen', 'transparent', 0), ...badge(isLight, 'magenta', 'transparent', 0), ...badge(isLight, TEXT_COLORS[scope][0], BG_COLORS[scope][0], NOTIFY_BORDER[scope][0]), ...badge(isLight, TEXT_COLORS[scope][1], BG_COLORS[scope][1], NOTIFY_BORDER[scope][1]), ...badge(isLight, TEXT_COLORS[scope][2], BG_COLORS[scope][2], NOTIFY_BORDER[scope][2]), ...colorForBucket(isLight, scope, path)];
|
|
899
|
+
}
|
|
900
|
+
case 'cache':
|
|
901
|
+
{
|
|
902
|
+
const scopePath = prefix ? `${scope} (${prefix})` : scope;
|
|
903
|
+
return [`%c@warp%c-%cdrive%c %c${scopePath}%c %c${subScop1}%c %c${subScop2}%c %c${subScop3}%c %c${subScop4}%c`, ...badge(isLight, 'lightgreen', 'transparent', 0), ...badge(isLight, 'magenta', 'transparent', 0), ...badge(isLight, TEXT_COLORS[scope][0], BG_COLORS[scope][0], NOTIFY_BORDER[scope][0]), ...badge(isLight, TEXT_COLORS[scope][1], BG_COLORS[scope][1], NOTIFY_BORDER[scope][1]), ...badge(isLight, TEXT_COLORS[scope][2], BG_COLORS[scope][2], NOTIFY_BORDER[scope][2]), ...colorForBucket(isLight, scope, subScop3), ...badge(isLight, TEXT_COLORS[scope][4], BG_COLORS[scope][4], NOTIFY_BORDER[scope][4])];
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
return [];
|
|
907
|
+
}
|
|
806
908
|
|
|
807
909
|
/**
|
|
808
910
|
@module @ember-data/store
|
|
@@ -1259,9 +1361,16 @@ class InstanceCache {
|
|
|
1259
1361
|
setCacheFor(record, cache);
|
|
1260
1362
|
StoreMap.set(record, this.store);
|
|
1261
1363
|
this.__instances.record.set(identifier, record);
|
|
1262
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1263
|
-
|
|
1264
|
-
|
|
1364
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1365
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1366
|
+
logGroup('reactive-ui', '', identifier.type, identifier.lid, 'created', '');
|
|
1367
|
+
// eslint-disable-next-line no-console
|
|
1368
|
+
console.log({
|
|
1369
|
+
properties
|
|
1370
|
+
});
|
|
1371
|
+
// eslint-disable-next-line no-console
|
|
1372
|
+
console.groupEnd();
|
|
1373
|
+
}
|
|
1265
1374
|
}
|
|
1266
1375
|
}
|
|
1267
1376
|
return record;
|
|
@@ -1307,9 +1416,10 @@ class InstanceCache {
|
|
|
1307
1416
|
this.store.identifierCache.forgetRecordIdentifier(identifier);
|
|
1308
1417
|
removeRecordDataFor(identifier);
|
|
1309
1418
|
this.store._requestCache._clearEntries(identifier);
|
|
1310
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1311
|
-
|
|
1312
|
-
|
|
1419
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1420
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1421
|
+
log('reactive-ui', '', identifier.type, identifier.lid, 'disconnected', '');
|
|
1422
|
+
}
|
|
1313
1423
|
}
|
|
1314
1424
|
}
|
|
1315
1425
|
unloadRecord(identifier) {
|
|
@@ -1325,9 +1435,11 @@ class InstanceCache {
|
|
|
1325
1435
|
})() : {};
|
|
1326
1436
|
}
|
|
1327
1437
|
}
|
|
1328
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1329
|
-
|
|
1330
|
-
|
|
1438
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1439
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1440
|
+
// eslint-disable-next-line no-console
|
|
1441
|
+
console.groupCollapsed(`InstanceCache: unloading record for ${String(identifier)}`);
|
|
1442
|
+
}
|
|
1331
1443
|
}
|
|
1332
1444
|
|
|
1333
1445
|
// TODO is this join still necessary?
|
|
@@ -1340,27 +1452,33 @@ class InstanceCache {
|
|
|
1340
1452
|
StoreMap.delete(record);
|
|
1341
1453
|
RecordCache.delete(record);
|
|
1342
1454
|
removeRecordDataFor(record);
|
|
1343
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1344
|
-
|
|
1345
|
-
|
|
1455
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1456
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1457
|
+
// eslint-disable-next-line no-console
|
|
1458
|
+
console.log(`InstanceCache: destroyed record for ${String(identifier)}`);
|
|
1459
|
+
}
|
|
1346
1460
|
}
|
|
1347
1461
|
}
|
|
1348
1462
|
if (cache) {
|
|
1349
1463
|
cache.unloadRecord(identifier);
|
|
1350
1464
|
removeRecordDataFor(identifier);
|
|
1351
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1352
|
-
|
|
1353
|
-
|
|
1465
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1466
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1467
|
+
// eslint-disable-next-line no-console
|
|
1468
|
+
console.log(`InstanceCache: destroyed cache for ${String(identifier)}`);
|
|
1469
|
+
}
|
|
1354
1470
|
}
|
|
1355
1471
|
} else {
|
|
1356
1472
|
this.disconnect(identifier);
|
|
1357
1473
|
}
|
|
1358
1474
|
this.store._requestCache._clearEntries(identifier);
|
|
1359
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1475
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1476
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1477
|
+
// eslint-disable-next-line no-console
|
|
1478
|
+
console.log(`InstanceCache: unloaded RecordData for ${String(identifier)}`);
|
|
1479
|
+
// eslint-disable-next-line no-console
|
|
1480
|
+
console.groupEnd();
|
|
1481
|
+
}
|
|
1364
1482
|
}
|
|
1365
1483
|
});
|
|
1366
1484
|
}
|
|
@@ -1415,9 +1533,11 @@ class InstanceCache {
|
|
|
1415
1533
|
warn(`Your ${type} record was saved to the server, but the response does not have an id.`, !(oldId !== null && id === null));
|
|
1416
1534
|
return;
|
|
1417
1535
|
}
|
|
1418
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1419
|
-
|
|
1420
|
-
|
|
1536
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1537
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1538
|
+
// eslint-disable-next-line no-console
|
|
1539
|
+
console.log(`InstanceCache: updating id to '${id}' for record ${String(identifier)}`);
|
|
1540
|
+
}
|
|
1421
1541
|
}
|
|
1422
1542
|
const existingIdentifier = this.store.identifierCache.peekRecordIdentifier({
|
|
1423
1543
|
type,
|
|
@@ -1734,7 +1854,9 @@ class CacheManager {
|
|
|
1734
1854
|
peek(identifier) {
|
|
1735
1855
|
return this.#cache.peek(identifier);
|
|
1736
1856
|
}
|
|
1737
|
-
|
|
1857
|
+
peekRemoteState(identifier) {
|
|
1858
|
+
return this.#cache.peekRemoteState(identifier);
|
|
1859
|
+
}
|
|
1738
1860
|
/**
|
|
1739
1861
|
* Peek the Cache for the existing request data associated with
|
|
1740
1862
|
* a cacheable request
|
|
@@ -1957,6 +2079,19 @@ class CacheManager {
|
|
|
1957
2079
|
return this.#cache.getAttr(identifier, propertyName);
|
|
1958
2080
|
}
|
|
1959
2081
|
|
|
2082
|
+
/**
|
|
2083
|
+
* Retrieve the remote state for an attribute from the cache
|
|
2084
|
+
*
|
|
2085
|
+
* @method getRemoteAttr
|
|
2086
|
+
* @public
|
|
2087
|
+
* @param identifier
|
|
2088
|
+
* @param propertyName
|
|
2089
|
+
* @return {unknown}
|
|
2090
|
+
*/
|
|
2091
|
+
getRemoteAttr(identifier, propertyName) {
|
|
2092
|
+
return this.#cache.getRemoteAttr(identifier, propertyName);
|
|
2093
|
+
}
|
|
2094
|
+
|
|
1960
2095
|
/**
|
|
1961
2096
|
* Mutate the data for an attribute in the cache
|
|
1962
2097
|
*
|
|
@@ -2081,6 +2216,19 @@ class CacheManager {
|
|
|
2081
2216
|
return this.#cache.getRelationship(identifier, propertyName);
|
|
2082
2217
|
}
|
|
2083
2218
|
|
|
2219
|
+
/**
|
|
2220
|
+
* Query the cache for the remote state of a relationship property
|
|
2221
|
+
*
|
|
2222
|
+
* @method getRelationship
|
|
2223
|
+
* @public
|
|
2224
|
+
* @param identifier
|
|
2225
|
+
* @param propertyName
|
|
2226
|
+
* @return resource relationship object
|
|
2227
|
+
*/
|
|
2228
|
+
getRemoteRelationship(identifier, propertyName) {
|
|
2229
|
+
return this.#cache.getRemoteRelationship(identifier, propertyName);
|
|
2230
|
+
}
|
|
2231
|
+
|
|
2084
2232
|
// Resource State
|
|
2085
2233
|
// ===============
|
|
2086
2234
|
|
|
@@ -2174,12 +2322,19 @@ function runLoopIsFlushing() {
|
|
|
2174
2322
|
//@ts-expect-error
|
|
2175
2323
|
return !!_backburner.currentInstance && _backburner._autorun !== true;
|
|
2176
2324
|
}
|
|
2325
|
+
function count(label) {
|
|
2326
|
+
// @ts-expect-error
|
|
2327
|
+
// eslint-disable-next-line
|
|
2328
|
+
globalThis.__WarpDriveMetricCountData[label] = (globalThis.__WarpDriveMetricCountData[label] || 0) + 1;
|
|
2329
|
+
}
|
|
2177
2330
|
function _unsubscribe(tokens, token, cache) {
|
|
2178
2331
|
const identifier = tokens.get(token);
|
|
2179
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
2180
|
-
if (
|
|
2181
|
-
|
|
2182
|
-
|
|
2332
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
|
|
2333
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
|
|
2334
|
+
if (!identifier) {
|
|
2335
|
+
// eslint-disable-next-line no-console
|
|
2336
|
+
console.log('Passed unknown unsubscribe token to unsubscribe', identifier);
|
|
2337
|
+
}
|
|
2183
2338
|
}
|
|
2184
2339
|
}
|
|
2185
2340
|
if (identifier) {
|
|
@@ -2287,16 +2442,14 @@ class NotificationManager {
|
|
|
2287
2442
|
}
|
|
2288
2443
|
})(!key || value === 'attributes' || value === 'relationships') : {};
|
|
2289
2444
|
if (!isStableIdentifier(identifier) && !isDocumentIdentifier(identifier)) {
|
|
2290
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
2291
|
-
|
|
2292
|
-
|
|
2445
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
|
|
2446
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
|
|
2447
|
+
// eslint-disable-next-line no-console
|
|
2448
|
+
console.log(`Notifying: Expected to receive a stable Identifier to notify '${value}' '${key || ''}' with, but ${String(identifier)} is not in the cache`, identifier);
|
|
2449
|
+
}
|
|
2293
2450
|
}
|
|
2294
2451
|
return false;
|
|
2295
2452
|
}
|
|
2296
|
-
if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS)) {
|
|
2297
|
-
// eslint-disable-next-line no-console
|
|
2298
|
-
console.log(`Buffering Notify: ${String(identifier.lid)}\t${value}\t${key || ''}`);
|
|
2299
|
-
}
|
|
2300
2453
|
const hasSubscribers = Boolean(this._cache.get(identifier)?.size);
|
|
2301
2454
|
if (isCacheOperationValue(value) || hasSubscribers) {
|
|
2302
2455
|
let buffer = this._buffered.get(identifier);
|
|
@@ -2305,7 +2458,22 @@ class NotificationManager {
|
|
|
2305
2458
|
this._buffered.set(identifier, buffer);
|
|
2306
2459
|
}
|
|
2307
2460
|
buffer.push([value, key]);
|
|
2308
|
-
|
|
2461
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
|
|
2462
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
|
|
2463
|
+
count(`notify ${'type' in identifier ? identifier.type : '<document>'} ${value} ${key}`);
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2466
|
+
if (!this._scheduleNotify()) {
|
|
2467
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
|
|
2468
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
|
|
2469
|
+
log('notify', 'buffered', `${'type' in identifier ? identifier.type : 'document'}`, identifier.lid, `${value}`, key || '');
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
} else if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
|
|
2474
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
|
|
2475
|
+
count(`DISCARDED notify ${'type' in identifier ? identifier.type : '<document>'} ${value} ${key}`);
|
|
2476
|
+
}
|
|
2309
2477
|
}
|
|
2310
2478
|
return hasSubscribers;
|
|
2311
2479
|
}
|
|
@@ -2316,14 +2484,15 @@ class NotificationManager {
|
|
|
2316
2484
|
const asyncFlush = this.store._enableAsyncFlush;
|
|
2317
2485
|
if (this._hasFlush) {
|
|
2318
2486
|
if (asyncFlush !== false && !runLoopIsFlushing()) {
|
|
2319
|
-
return;
|
|
2487
|
+
return false;
|
|
2320
2488
|
}
|
|
2321
2489
|
}
|
|
2322
2490
|
if (asyncFlush && !runLoopIsFlushing()) {
|
|
2323
2491
|
this._hasFlush = true;
|
|
2324
|
-
return;
|
|
2492
|
+
return false;
|
|
2325
2493
|
}
|
|
2326
2494
|
this._flush();
|
|
2495
|
+
return true;
|
|
2327
2496
|
}
|
|
2328
2497
|
_flush() {
|
|
2329
2498
|
const buffered = this._buffered;
|
|
@@ -2341,9 +2510,10 @@ class NotificationManager {
|
|
|
2341
2510
|
this._onFlushCB = undefined;
|
|
2342
2511
|
}
|
|
2343
2512
|
_flushNotification(identifier, value, key) {
|
|
2344
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
2345
|
-
|
|
2346
|
-
|
|
2513
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
|
|
2514
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
|
|
2515
|
+
log('notify', '', `${'type' in identifier ? identifier.type : 'document'}`, identifier.lid, `${value}`, key || '');
|
|
2516
|
+
}
|
|
2347
2517
|
}
|
|
2348
2518
|
|
|
2349
2519
|
// TODO for documents this will need to switch based on Identifier kind
|
|
@@ -2882,7 +3052,7 @@ class IdentifierArray {
|
|
|
2882
3052
|
return false;
|
|
2883
3053
|
}
|
|
2884
3054
|
const original = target[index];
|
|
2885
|
-
const newIdentifier = extractIdentifierFromRecord$
|
|
3055
|
+
const newIdentifier = extractIdentifierFromRecord$2(value);
|
|
2886
3056
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2887
3057
|
if (!test) {
|
|
2888
3058
|
throw new Error(`Expected a record`);
|
|
@@ -2923,7 +3093,7 @@ class IdentifierArray {
|
|
|
2923
3093
|
return Reflect.deleteProperty(target, prop);
|
|
2924
3094
|
},
|
|
2925
3095
|
getPrototypeOf() {
|
|
2926
|
-
return
|
|
3096
|
+
return Array.prototype;
|
|
2927
3097
|
}
|
|
2928
3098
|
});
|
|
2929
3099
|
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_A_USAGE)) {
|
|
@@ -3505,7 +3675,7 @@ if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_ARRAY_LIKE
|
|
|
3505
3675
|
// @ts-expect-error
|
|
3506
3676
|
IdentifierArray.prototype.lastObject = null;
|
|
3507
3677
|
}
|
|
3508
|
-
function assertRecordPassedToHasMany(record) {
|
|
3678
|
+
function assertRecordPassedToHasMany$1(record) {
|
|
3509
3679
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
3510
3680
|
if (!test) {
|
|
3511
3681
|
throw new Error(`All elements of a hasMany relationship must be instances of Model, you passed $${typeof record}`);
|
|
@@ -3519,24 +3689,24 @@ function assertRecordPassedToHasMany(record) {
|
|
|
3519
3689
|
}
|
|
3520
3690
|
}()) : {};
|
|
3521
3691
|
}
|
|
3522
|
-
function extractIdentifierFromRecord$
|
|
3692
|
+
function extractIdentifierFromRecord$2(recordOrPromiseRecord) {
|
|
3523
3693
|
if (!recordOrPromiseRecord) {
|
|
3524
3694
|
return null;
|
|
3525
3695
|
}
|
|
3526
|
-
if (isPromiseRecord$
|
|
3696
|
+
if (isPromiseRecord$2(recordOrPromiseRecord)) {
|
|
3527
3697
|
const content = recordOrPromiseRecord.content;
|
|
3528
3698
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
3529
3699
|
if (!test) {
|
|
3530
3700
|
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.');
|
|
3531
3701
|
}
|
|
3532
3702
|
})(content !== undefined && content !== null) : {};
|
|
3533
|
-
assertRecordPassedToHasMany(content);
|
|
3703
|
+
assertRecordPassedToHasMany$1(content);
|
|
3534
3704
|
return recordIdentifierFor(content);
|
|
3535
3705
|
}
|
|
3536
|
-
assertRecordPassedToHasMany(recordOrPromiseRecord);
|
|
3706
|
+
assertRecordPassedToHasMany$1(recordOrPromiseRecord);
|
|
3537
3707
|
return recordIdentifierFor(recordOrPromiseRecord);
|
|
3538
3708
|
}
|
|
3539
|
-
function isPromiseRecord$
|
|
3709
|
+
function isPromiseRecord$2(record) {
|
|
3540
3710
|
return Boolean(typeof record === 'object' && record && 'then' in record);
|
|
3541
3711
|
}
|
|
3542
3712
|
|
|
@@ -3631,6 +3801,9 @@ class RecordArrayManager {
|
|
|
3631
3801
|
sync(array, pending, this._set.get(array));
|
|
3632
3802
|
this._pending.delete(array);
|
|
3633
3803
|
}
|
|
3804
|
+
mutate(mutation) {
|
|
3805
|
+
this.store.cache.mutate(mutation);
|
|
3806
|
+
}
|
|
3634
3807
|
|
|
3635
3808
|
/**
|
|
3636
3809
|
Get the `RecordArray` for a modelName, which contains all loaded records of
|
|
@@ -4147,6 +4320,26 @@ function constructResource(type, id, lid) {
|
|
|
4147
4320
|
*/
|
|
4148
4321
|
// this import location is deprecated but breaks in 4.8 and older
|
|
4149
4322
|
|
|
4323
|
+
// @ts-expect-error adding to globalThis
|
|
4324
|
+
globalThis.setWarpDriveLogging = setLogging;
|
|
4325
|
+
|
|
4326
|
+
// @ts-expect-error adding to globalThis
|
|
4327
|
+
globalThis.getWarpDriveRuntimeConfig = getRuntimeConfig;
|
|
4328
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
|
|
4329
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
|
|
4330
|
+
// @ts-expect-error
|
|
4331
|
+
// eslint-disable-next-line
|
|
4332
|
+
globalThis.__WarpDriveMetricCountData = globalThis.__WarpDriveMetricCountData || {};
|
|
4333
|
+
|
|
4334
|
+
// @ts-expect-error
|
|
4335
|
+
globalThis.getWarpDriveMetricCounts = () => {
|
|
4336
|
+
// @ts-expect-error
|
|
4337
|
+
// eslint-disable-next-line
|
|
4338
|
+
return globalThis.__WarpDriveMetricCountData;
|
|
4339
|
+
};
|
|
4340
|
+
}
|
|
4341
|
+
}
|
|
4342
|
+
|
|
4150
4343
|
// `AwaitedKeys` is needed here to resolve any promise types like `PromiseBelongsTo`.
|
|
4151
4344
|
|
|
4152
4345
|
/**
|
|
@@ -4274,12 +4467,9 @@ class Store extends BaseClass {
|
|
|
4274
4467
|
* import Fetch from '@ember-data/request/fetch';
|
|
4275
4468
|
*
|
|
4276
4469
|
* class extends Store {
|
|
4277
|
-
*
|
|
4278
|
-
*
|
|
4279
|
-
*
|
|
4280
|
-
* this.requestManager.use([Fetch]);
|
|
4281
|
-
* this.requestManager.useCache(CacheHandler);
|
|
4282
|
-
* }
|
|
4470
|
+
* requestManager = new RequestManager()
|
|
4471
|
+
* .use([Fetch])
|
|
4472
|
+
* .useCache(CacheHandler);
|
|
4283
4473
|
* }
|
|
4284
4474
|
* ```
|
|
4285
4475
|
*
|
|
@@ -4521,7 +4711,7 @@ class Store extends BaseClass {
|
|
|
4521
4711
|
// the user has had the chance to set the prop.
|
|
4522
4712
|
const opts = {
|
|
4523
4713
|
store: this,
|
|
4524
|
-
[EnableHydration]: true
|
|
4714
|
+
[EnableHydration]: requestConfig[EnableHydration] ?? true
|
|
4525
4715
|
};
|
|
4526
4716
|
if (requestConfig.records) {
|
|
4527
4717
|
const identifierCache = this.identifierCache;
|
|
@@ -4532,22 +4722,26 @@ class Store extends BaseClass {
|
|
|
4532
4722
|
opts.disableTestWaiter = typeof requestConfig.disableTestWaiter === 'boolean' ? requestConfig.disableTestWaiter : true;
|
|
4533
4723
|
}
|
|
4534
4724
|
}
|
|
4535
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4725
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_REQUESTS)) {
|
|
4726
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_REQUESTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_REQUESTS) {
|
|
4727
|
+
let options;
|
|
4728
|
+
try {
|
|
4729
|
+
options = JSON.parse(JSON.stringify(requestConfig));
|
|
4730
|
+
} catch {
|
|
4731
|
+
options = requestConfig;
|
|
4732
|
+
}
|
|
4733
|
+
// eslint-disable-next-line no-console
|
|
4734
|
+
console.log(`request: [[START]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`, options);
|
|
4541
4735
|
}
|
|
4542
|
-
// eslint-disable-next-line no-console
|
|
4543
|
-
console.log(`request: [[START]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`, options);
|
|
4544
4736
|
}
|
|
4545
4737
|
const request = Object.assign({}, requestConfig, opts);
|
|
4546
4738
|
const future = this.requestManager.request(request);
|
|
4547
4739
|
future.onFinalize(() => {
|
|
4548
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
4549
|
-
|
|
4550
|
-
|
|
4740
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_REQUESTS)) {
|
|
4741
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_REQUESTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_REQUESTS) {
|
|
4742
|
+
// eslint-disable-next-line no-console
|
|
4743
|
+
console.log(`request: [[FINALIZE]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`);
|
|
4744
|
+
}
|
|
4551
4745
|
}
|
|
4552
4746
|
// skip flush for legacy belongsTo
|
|
4553
4747
|
if (requestConfig.op === 'findBelongsTo' && !requestConfig.url) {
|
|
@@ -4753,9 +4947,8 @@ class Store extends BaseClass {
|
|
|
4753
4947
|
This will cause the record to be destroyed and freed up for garbage collection.
|
|
4754
4948
|
Example
|
|
4755
4949
|
```javascript
|
|
4756
|
-
store.findRecord('post', '1')
|
|
4757
|
-
|
|
4758
|
-
});
|
|
4950
|
+
const { content: { data: post } } = await store.request(findRecord({ type: 'post', id: '1' }));
|
|
4951
|
+
store.unloadRecord(post);
|
|
4759
4952
|
```
|
|
4760
4953
|
@method unloadRecord
|
|
4761
4954
|
@public
|
|
@@ -5944,14 +6137,16 @@ class Store extends BaseClass {
|
|
|
5944
6137
|
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
5945
6138
|
assertDestroyingStore(this, '_push');
|
|
5946
6139
|
}
|
|
5947
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
6140
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_PAYLOADS)) {
|
|
6141
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_PAYLOADS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_PAYLOADS) {
|
|
6142
|
+
try {
|
|
6143
|
+
const data = JSON.parse(JSON.stringify(jsonApiDoc));
|
|
6144
|
+
// eslint-disable-next-line no-console
|
|
6145
|
+
console.log('EmberData | Payload - push', data);
|
|
6146
|
+
} catch {
|
|
6147
|
+
// eslint-disable-next-line no-console
|
|
6148
|
+
console.log('EmberData | Payload - push', jsonApiDoc);
|
|
6149
|
+
}
|
|
5955
6150
|
}
|
|
5956
6151
|
}
|
|
5957
6152
|
if (asyncFlush) {
|
|
@@ -6174,9 +6369,9 @@ function normalizeProperties(store, identifier, properties) {
|
|
|
6174
6369
|
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
6175
6370
|
assertRecordsPassedToHasMany(properties[prop]);
|
|
6176
6371
|
}
|
|
6177
|
-
properties[prop] = extractIdentifiersFromRecords(properties[prop]);
|
|
6372
|
+
properties[prop] = extractIdentifiersFromRecords$1(properties[prop]);
|
|
6178
6373
|
} else if (field.kind === 'belongsTo') {
|
|
6179
|
-
properties[prop] = extractIdentifierFromRecord(properties[prop]);
|
|
6374
|
+
properties[prop] = extractIdentifierFromRecord$1(properties[prop]);
|
|
6180
6375
|
}
|
|
6181
6376
|
}
|
|
6182
6377
|
}
|
|
@@ -6204,16 +6399,16 @@ function assertRecordsPassedToHasMany(records) {
|
|
|
6204
6399
|
});
|
|
6205
6400
|
}()) : {};
|
|
6206
6401
|
}
|
|
6207
|
-
function extractIdentifiersFromRecords(records) {
|
|
6208
|
-
return records.map(record => extractIdentifierFromRecord(record));
|
|
6402
|
+
function extractIdentifiersFromRecords$1(records) {
|
|
6403
|
+
return records.map(record => extractIdentifierFromRecord$1(record));
|
|
6209
6404
|
}
|
|
6210
|
-
function extractIdentifierFromRecord(recordOrPromiseRecord) {
|
|
6405
|
+
function extractIdentifierFromRecord$1(recordOrPromiseRecord) {
|
|
6211
6406
|
if (!recordOrPromiseRecord) {
|
|
6212
6407
|
return null;
|
|
6213
6408
|
}
|
|
6214
6409
|
const extract = recordIdentifierFor;
|
|
6215
6410
|
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_PROMISE_PROXIES)) {
|
|
6216
|
-
if (isPromiseRecord(recordOrPromiseRecord)) {
|
|
6411
|
+
if (isPromiseRecord$1(recordOrPromiseRecord)) {
|
|
6217
6412
|
const content = recordOrPromiseRecord.content;
|
|
6218
6413
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
6219
6414
|
if (!test) {
|
|
@@ -6234,7 +6429,7 @@ function extractIdentifierFromRecord(recordOrPromiseRecord) {
|
|
|
6234
6429
|
}
|
|
6235
6430
|
return extract(recordOrPromiseRecord);
|
|
6236
6431
|
}
|
|
6237
|
-
function isPromiseRecord(record) {
|
|
6432
|
+
function isPromiseRecord$1(record) {
|
|
6238
6433
|
return typeof record === 'object' && !!record && 'then' in record && typeof record.then === 'function';
|
|
6239
6434
|
}
|
|
6240
6435
|
|
|
@@ -6882,6 +7077,503 @@ function fetchContentAndHydrate(next, context, identifier, priority) {
|
|
|
6882
7077
|
/**
|
|
6883
7078
|
@module @ember-data/store
|
|
6884
7079
|
*/
|
|
7080
|
+
/**
|
|
7081
|
+
A `ManyArray` is a `MutableArray` that represents the contents of a has-many
|
|
7082
|
+
relationship.
|
|
7083
|
+
|
|
7084
|
+
The `ManyArray` is instantiated lazily the first time the relationship is
|
|
7085
|
+
requested.
|
|
7086
|
+
|
|
7087
|
+
This class is not intended to be directly instantiated by consuming applications.
|
|
7088
|
+
|
|
7089
|
+
### Inverses
|
|
7090
|
+
|
|
7091
|
+
Often, the relationships in Ember Data applications will have
|
|
7092
|
+
an inverse. For example, imagine the following models are
|
|
7093
|
+
defined:
|
|
7094
|
+
|
|
7095
|
+
```app/models/post.js
|
|
7096
|
+
import Model, { hasMany } from '@ember-data/model';
|
|
7097
|
+
|
|
7098
|
+
export default class PostModel extends Model {
|
|
7099
|
+
@hasMany('comment') comments;
|
|
7100
|
+
}
|
|
7101
|
+
```
|
|
7102
|
+
|
|
7103
|
+
```app/models/comment.js
|
|
7104
|
+
import Model, { belongsTo } from '@ember-data/model';
|
|
7105
|
+
|
|
7106
|
+
export default class CommentModel extends Model {
|
|
7107
|
+
@belongsTo('post') post;
|
|
7108
|
+
}
|
|
7109
|
+
```
|
|
7110
|
+
|
|
7111
|
+
If you created a new instance of `Post` and added
|
|
7112
|
+
a `Comment` record to its `comments` has-many
|
|
7113
|
+
relationship, you would expect the comment's `post`
|
|
7114
|
+
property to be set to the post that contained
|
|
7115
|
+
the has-many.
|
|
7116
|
+
|
|
7117
|
+
We call the record to which a relationship belongs-to the
|
|
7118
|
+
relationship's _owner_.
|
|
7119
|
+
|
|
7120
|
+
@class ManyArray
|
|
7121
|
+
@public
|
|
7122
|
+
*/
|
|
7123
|
+
class RelatedCollection extends IdentifierArray {
|
|
7124
|
+
/**
|
|
7125
|
+
The loading state of this array
|
|
7126
|
+
@property {Boolean} isLoaded
|
|
7127
|
+
@public
|
|
7128
|
+
*/
|
|
7129
|
+
|
|
7130
|
+
/**
|
|
7131
|
+
`true` if the relationship is polymorphic, `false` otherwise.
|
|
7132
|
+
@property {Boolean} isPolymorphic
|
|
7133
|
+
@private
|
|
7134
|
+
*/
|
|
7135
|
+
|
|
7136
|
+
/**
|
|
7137
|
+
Metadata associated with the request for async hasMany relationships.
|
|
7138
|
+
Example
|
|
7139
|
+
Given that the server returns the following JSON payload when fetching a
|
|
7140
|
+
hasMany relationship:
|
|
7141
|
+
```js
|
|
7142
|
+
{
|
|
7143
|
+
"comments": [{
|
|
7144
|
+
"id": 1,
|
|
7145
|
+
"comment": "This is the first comment",
|
|
7146
|
+
}, {
|
|
7147
|
+
// ...
|
|
7148
|
+
}],
|
|
7149
|
+
"meta": {
|
|
7150
|
+
"page": 1,
|
|
7151
|
+
"total": 5
|
|
7152
|
+
}
|
|
7153
|
+
}
|
|
7154
|
+
```
|
|
7155
|
+
You can then access the meta data via the `meta` property:
|
|
7156
|
+
```js
|
|
7157
|
+
let comments = await post.comments;
|
|
7158
|
+
let meta = comments.meta;
|
|
7159
|
+
// meta.page => 1
|
|
7160
|
+
// meta.total => 5
|
|
7161
|
+
```
|
|
7162
|
+
@property {Object | null} meta
|
|
7163
|
+
@public
|
|
7164
|
+
*/
|
|
7165
|
+
|
|
7166
|
+
/**
|
|
7167
|
+
* Retrieve the links for this relationship
|
|
7168
|
+
*
|
|
7169
|
+
@property {Object | null} links
|
|
7170
|
+
@public
|
|
7171
|
+
*/
|
|
7172
|
+
|
|
7173
|
+
constructor(options) {
|
|
7174
|
+
super(options);
|
|
7175
|
+
this.isLoaded = options.isLoaded || false;
|
|
7176
|
+
this.isAsync = options.isAsync || false;
|
|
7177
|
+
this.isPolymorphic = options.isPolymorphic || false;
|
|
7178
|
+
this.identifier = options.identifier;
|
|
7179
|
+
this.key = options.key;
|
|
7180
|
+
}
|
|
7181
|
+
[MUTATE](target, receiver, prop, args, _SIGNAL) {
|
|
7182
|
+
switch (prop) {
|
|
7183
|
+
case 'length 0':
|
|
7184
|
+
{
|
|
7185
|
+
Reflect.set(target, 'length', 0);
|
|
7186
|
+
mutateReplaceRelatedRecords(this, [], _SIGNAL);
|
|
7187
|
+
return true;
|
|
7188
|
+
}
|
|
7189
|
+
case 'replace cell':
|
|
7190
|
+
{
|
|
7191
|
+
const [index, prior, value] = args;
|
|
7192
|
+
target[index] = value;
|
|
7193
|
+
mutateReplaceRelatedRecord(this, {
|
|
7194
|
+
value,
|
|
7195
|
+
prior,
|
|
7196
|
+
index
|
|
7197
|
+
}, _SIGNAL);
|
|
7198
|
+
return true;
|
|
7199
|
+
}
|
|
7200
|
+
case 'push':
|
|
7201
|
+
{
|
|
7202
|
+
const newValues = extractIdentifiersFromRecords(args);
|
|
7203
|
+
assertNoDuplicates(this, target, currentState => currentState.push(...newValues), `Cannot push duplicates to a hasMany's state.`);
|
|
7204
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
7205
|
+
// dedupe
|
|
7206
|
+
const seen = new Set(target);
|
|
7207
|
+
const unique = new Set();
|
|
7208
|
+
args.forEach(item => {
|
|
7209
|
+
const identifier = recordIdentifierFor(item);
|
|
7210
|
+
if (!seen.has(identifier)) {
|
|
7211
|
+
seen.add(identifier);
|
|
7212
|
+
unique.add(item);
|
|
7213
|
+
}
|
|
7214
|
+
});
|
|
7215
|
+
const newArgs = Array.from(unique);
|
|
7216
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
7217
|
+
if (newArgs.length) {
|
|
7218
|
+
mutateAddToRelatedRecords(this, {
|
|
7219
|
+
value: extractIdentifiersFromRecords(newArgs)
|
|
7220
|
+
}, _SIGNAL);
|
|
7221
|
+
}
|
|
7222
|
+
return result;
|
|
7223
|
+
}
|
|
7224
|
+
|
|
7225
|
+
// else, no dedupe, error on duplicates
|
|
7226
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
7227
|
+
if (newValues.length) {
|
|
7228
|
+
mutateAddToRelatedRecords(this, {
|
|
7229
|
+
value: newValues
|
|
7230
|
+
}, _SIGNAL);
|
|
7231
|
+
}
|
|
7232
|
+
return result;
|
|
7233
|
+
}
|
|
7234
|
+
case 'pop':
|
|
7235
|
+
{
|
|
7236
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
7237
|
+
if (result) {
|
|
7238
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
7239
|
+
value: recordIdentifierFor(result)
|
|
7240
|
+
}, _SIGNAL);
|
|
7241
|
+
}
|
|
7242
|
+
return result;
|
|
7243
|
+
}
|
|
7244
|
+
case 'unshift':
|
|
7245
|
+
{
|
|
7246
|
+
const newValues = extractIdentifiersFromRecords(args);
|
|
7247
|
+
assertNoDuplicates(this, target, currentState => currentState.unshift(...newValues), `Cannot unshift duplicates to a hasMany's state.`);
|
|
7248
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
7249
|
+
// dedupe
|
|
7250
|
+
const seen = new Set(target);
|
|
7251
|
+
const unique = new Set();
|
|
7252
|
+
args.forEach(item => {
|
|
7253
|
+
const identifier = recordIdentifierFor(item);
|
|
7254
|
+
if (!seen.has(identifier)) {
|
|
7255
|
+
seen.add(identifier);
|
|
7256
|
+
unique.add(item);
|
|
7257
|
+
}
|
|
7258
|
+
});
|
|
7259
|
+
const newArgs = Array.from(unique);
|
|
7260
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
7261
|
+
if (newArgs.length) {
|
|
7262
|
+
mutateAddToRelatedRecords(this, {
|
|
7263
|
+
value: extractIdentifiersFromRecords(newArgs),
|
|
7264
|
+
index: 0
|
|
7265
|
+
}, _SIGNAL);
|
|
7266
|
+
}
|
|
7267
|
+
return result;
|
|
7268
|
+
}
|
|
7269
|
+
|
|
7270
|
+
// else, no dedupe, error on duplicates
|
|
7271
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
7272
|
+
if (newValues.length) {
|
|
7273
|
+
mutateAddToRelatedRecords(this, {
|
|
7274
|
+
value: newValues,
|
|
7275
|
+
index: 0
|
|
7276
|
+
}, _SIGNAL);
|
|
7277
|
+
}
|
|
7278
|
+
return result;
|
|
7279
|
+
}
|
|
7280
|
+
case 'shift':
|
|
7281
|
+
{
|
|
7282
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
7283
|
+
if (result) {
|
|
7284
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
7285
|
+
value: recordIdentifierFor(result),
|
|
7286
|
+
index: 0
|
|
7287
|
+
}, _SIGNAL);
|
|
7288
|
+
}
|
|
7289
|
+
return result;
|
|
7290
|
+
}
|
|
7291
|
+
case 'sort':
|
|
7292
|
+
{
|
|
7293
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
7294
|
+
mutateSortRelatedRecords(this, result.map(recordIdentifierFor), _SIGNAL);
|
|
7295
|
+
return result;
|
|
7296
|
+
}
|
|
7297
|
+
case 'splice':
|
|
7298
|
+
{
|
|
7299
|
+
const [start, deleteCount, ...adds] = args;
|
|
7300
|
+
|
|
7301
|
+
// detect a full replace
|
|
7302
|
+
if (start === 0 && deleteCount === this[SOURCE].length) {
|
|
7303
|
+
const newValues = extractIdentifiersFromRecords(adds);
|
|
7304
|
+
assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot replace a hasMany's state with a new state that contains duplicates.`);
|
|
7305
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
7306
|
+
// dedupe
|
|
7307
|
+
const current = new Set(adds);
|
|
7308
|
+
const unique = Array.from(current);
|
|
7309
|
+
const uniqueIdentifiers = Array.from(new Set(newValues));
|
|
7310
|
+
const newArgs = [start, deleteCount].concat(unique);
|
|
7311
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
7312
|
+
mutateReplaceRelatedRecords(this, uniqueIdentifiers, _SIGNAL);
|
|
7313
|
+
return result;
|
|
7314
|
+
}
|
|
7315
|
+
|
|
7316
|
+
// else, no dedupe, error on duplicates
|
|
7317
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
7318
|
+
mutateReplaceRelatedRecords(this, newValues, _SIGNAL);
|
|
7319
|
+
return result;
|
|
7320
|
+
}
|
|
7321
|
+
const newValues = extractIdentifiersFromRecords(adds);
|
|
7322
|
+
assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot splice a hasMany's state with a new state that contains duplicates.`);
|
|
7323
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
7324
|
+
// dedupe
|
|
7325
|
+
const currentState = target.slice();
|
|
7326
|
+
currentState.splice(start, deleteCount);
|
|
7327
|
+
const seen = new Set(currentState);
|
|
7328
|
+
const unique = [];
|
|
7329
|
+
adds.forEach(item => {
|
|
7330
|
+
const identifier = recordIdentifierFor(item);
|
|
7331
|
+
if (!seen.has(identifier)) {
|
|
7332
|
+
seen.add(identifier);
|
|
7333
|
+
unique.push(item);
|
|
7334
|
+
}
|
|
7335
|
+
});
|
|
7336
|
+
const newArgs = [start, deleteCount, ...unique];
|
|
7337
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
7338
|
+
if (deleteCount > 0) {
|
|
7339
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
7340
|
+
value: result.map(recordIdentifierFor),
|
|
7341
|
+
index: start
|
|
7342
|
+
}, _SIGNAL);
|
|
7343
|
+
}
|
|
7344
|
+
if (unique.length > 0) {
|
|
7345
|
+
mutateAddToRelatedRecords(this, {
|
|
7346
|
+
value: extractIdentifiersFromRecords(unique),
|
|
7347
|
+
index: start
|
|
7348
|
+
}, _SIGNAL);
|
|
7349
|
+
}
|
|
7350
|
+
return result;
|
|
7351
|
+
}
|
|
7352
|
+
|
|
7353
|
+
// else, no dedupe, error on duplicates
|
|
7354
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
7355
|
+
if (deleteCount > 0) {
|
|
7356
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
7357
|
+
value: result.map(recordIdentifierFor),
|
|
7358
|
+
index: start
|
|
7359
|
+
}, _SIGNAL);
|
|
7360
|
+
}
|
|
7361
|
+
if (newValues.length > 0) {
|
|
7362
|
+
mutateAddToRelatedRecords(this, {
|
|
7363
|
+
value: newValues,
|
|
7364
|
+
index: start
|
|
7365
|
+
}, _SIGNAL);
|
|
7366
|
+
}
|
|
7367
|
+
return result;
|
|
7368
|
+
}
|
|
7369
|
+
default:
|
|
7370
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
7371
|
+
{
|
|
7372
|
+
throw new Error(`unable to convert ${prop} into a transaction that updates the cache state for this record array`);
|
|
7373
|
+
}
|
|
7374
|
+
})() : {};
|
|
7375
|
+
}
|
|
7376
|
+
}
|
|
7377
|
+
notify() {
|
|
7378
|
+
const signal = this[ARRAY_SIGNAL];
|
|
7379
|
+
signal.shouldReset = true;
|
|
7380
|
+
notifyArray(this);
|
|
7381
|
+
}
|
|
7382
|
+
|
|
7383
|
+
/**
|
|
7384
|
+
Reloads all of the records in the manyArray. If the manyArray
|
|
7385
|
+
holds a relationship that was originally fetched using a links url
|
|
7386
|
+
EmberData will revisit the original links url to repopulate the
|
|
7387
|
+
relationship.
|
|
7388
|
+
If the ManyArray holds the result of a `store.query()` reload will
|
|
7389
|
+
re-run the original query.
|
|
7390
|
+
Example
|
|
7391
|
+
```javascript
|
|
7392
|
+
let user = store.peekRecord('user', '1')
|
|
7393
|
+
await login(user);
|
|
7394
|
+
let permissions = await user.permissions;
|
|
7395
|
+
await permissions.reload();
|
|
7396
|
+
```
|
|
7397
|
+
@method reload
|
|
7398
|
+
@public
|
|
7399
|
+
*/
|
|
7400
|
+
reload(options) {
|
|
7401
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
7402
|
+
if (!test) {
|
|
7403
|
+
throw new Error(`Expected the manager for ManyArray to implement reloadHasMany`);
|
|
7404
|
+
}
|
|
7405
|
+
})(typeof this._manager.reloadHasMany === 'function') : {};
|
|
7406
|
+
// TODO this is odd, we don't ask the store for anything else like this?
|
|
7407
|
+
return this._manager.reloadHasMany(this.key, options);
|
|
7408
|
+
}
|
|
7409
|
+
|
|
7410
|
+
/**
|
|
7411
|
+
Saves all of the records in the `ManyArray`.
|
|
7412
|
+
Note: this API can only be used in legacy mode with a configured Adapter.
|
|
7413
|
+
Example
|
|
7414
|
+
```javascript
|
|
7415
|
+
const { content: { data: inbox } } = await store.request(findRecord({ type: 'inbox', id: '1' }));
|
|
7416
|
+
let messages = await inbox.messages;
|
|
7417
|
+
messages.forEach((message) => {
|
|
7418
|
+
message.isRead = true;
|
|
7419
|
+
});
|
|
7420
|
+
messages.save();
|
|
7421
|
+
```
|
|
7422
|
+
@method save
|
|
7423
|
+
@public
|
|
7424
|
+
@return {PromiseArray} promise
|
|
7425
|
+
*/
|
|
7426
|
+
|
|
7427
|
+
/**
|
|
7428
|
+
Create a child record within the owner
|
|
7429
|
+
@method createRecord
|
|
7430
|
+
@public
|
|
7431
|
+
@param {Object} hash
|
|
7432
|
+
@return {Model} record
|
|
7433
|
+
*/
|
|
7434
|
+
createRecord(hash) {
|
|
7435
|
+
const {
|
|
7436
|
+
store
|
|
7437
|
+
} = this;
|
|
7438
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
7439
|
+
if (!test) {
|
|
7440
|
+
throw new Error(`Expected modelName to be set`);
|
|
7441
|
+
}
|
|
7442
|
+
})(this.modelName) : {};
|
|
7443
|
+
const record = store.createRecord(this.modelName, hash);
|
|
7444
|
+
this.push(record);
|
|
7445
|
+
return record;
|
|
7446
|
+
}
|
|
7447
|
+
destroy() {
|
|
7448
|
+
super.destroy(false);
|
|
7449
|
+
}
|
|
7450
|
+
}
|
|
7451
|
+
RelatedCollection.prototype.isAsync = false;
|
|
7452
|
+
RelatedCollection.prototype.isPolymorphic = false;
|
|
7453
|
+
RelatedCollection.prototype.identifier = null;
|
|
7454
|
+
RelatedCollection.prototype.cache = null;
|
|
7455
|
+
RelatedCollection.prototype._inverseIsAsync = false;
|
|
7456
|
+
RelatedCollection.prototype.key = '';
|
|
7457
|
+
RelatedCollection.prototype.DEPRECATED_CLASS_NAME = 'ManyArray';
|
|
7458
|
+
function assertRecordPassedToHasMany(record) {
|
|
7459
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
7460
|
+
if (!test) {
|
|
7461
|
+
throw new Error(`All elements of a hasMany relationship must be instances of Model, you passed ${typeof record}`);
|
|
7462
|
+
}
|
|
7463
|
+
})(function () {
|
|
7464
|
+
try {
|
|
7465
|
+
recordIdentifierFor(record);
|
|
7466
|
+
return true;
|
|
7467
|
+
} catch {
|
|
7468
|
+
return false;
|
|
7469
|
+
}
|
|
7470
|
+
}()) : {};
|
|
7471
|
+
}
|
|
7472
|
+
function extractIdentifiersFromRecords(records) {
|
|
7473
|
+
return records.map(extractIdentifierFromRecord);
|
|
7474
|
+
}
|
|
7475
|
+
function extractIdentifierFromRecord(recordOrPromiseRecord) {
|
|
7476
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_PROMISE_PROXIES)) {
|
|
7477
|
+
if (isPromiseRecord(recordOrPromiseRecord)) {
|
|
7478
|
+
const content = recordOrPromiseRecord.content;
|
|
7479
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
7480
|
+
if (!test) {
|
|
7481
|
+
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.');
|
|
7482
|
+
}
|
|
7483
|
+
})(content !== undefined && content !== null) : {};
|
|
7484
|
+
deprecate(`You passed in a PromiseProxy to a Relationship API that now expects a resolved value. await the value before setting it.`, false, {
|
|
7485
|
+
id: 'ember-data:deprecate-promise-proxies',
|
|
7486
|
+
until: '5.0',
|
|
7487
|
+
since: {
|
|
7488
|
+
enabled: '4.7',
|
|
7489
|
+
available: '4.7'
|
|
7490
|
+
},
|
|
7491
|
+
for: 'ember-data'
|
|
7492
|
+
});
|
|
7493
|
+
assertRecordPassedToHasMany(content);
|
|
7494
|
+
return recordIdentifierFor(content);
|
|
7495
|
+
}
|
|
7496
|
+
}
|
|
7497
|
+
assertRecordPassedToHasMany(recordOrPromiseRecord);
|
|
7498
|
+
return recordIdentifierFor(recordOrPromiseRecord);
|
|
7499
|
+
}
|
|
7500
|
+
function isPromiseRecord(record) {
|
|
7501
|
+
return Boolean(typeof record === 'object' && record && 'then' in record);
|
|
7502
|
+
}
|
|
7503
|
+
function assertNoDuplicates(collection, target, callback, reason) {
|
|
7504
|
+
const state = target.slice();
|
|
7505
|
+
callback(state);
|
|
7506
|
+
if (state.length !== new Set(state).size) {
|
|
7507
|
+
const duplicates = state.filter((currentValue, currentIndex) => state.indexOf(currentValue) !== currentIndex);
|
|
7508
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
7509
|
+
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, {
|
|
7510
|
+
id: 'ember-data:deprecate-many-array-duplicates',
|
|
7511
|
+
for: 'ember-data',
|
|
7512
|
+
until: '6.0',
|
|
7513
|
+
since: {
|
|
7514
|
+
enabled: '5.3',
|
|
7515
|
+
available: '4.13'
|
|
7516
|
+
}
|
|
7517
|
+
});
|
|
7518
|
+
} else {
|
|
7519
|
+
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- ')}`);
|
|
7520
|
+
}
|
|
7521
|
+
}
|
|
7522
|
+
}
|
|
7523
|
+
function mutateAddToRelatedRecords(collection, operationInfo, _SIGNAL) {
|
|
7524
|
+
mutate(collection, {
|
|
7525
|
+
op: 'addToRelatedRecords',
|
|
7526
|
+
record: collection.identifier,
|
|
7527
|
+
field: collection.key,
|
|
7528
|
+
...operationInfo
|
|
7529
|
+
}, _SIGNAL);
|
|
7530
|
+
}
|
|
7531
|
+
function mutateRemoveFromRelatedRecords(collection, operationInfo, _SIGNAL) {
|
|
7532
|
+
mutate(collection, {
|
|
7533
|
+
op: 'removeFromRelatedRecords',
|
|
7534
|
+
record: collection.identifier,
|
|
7535
|
+
field: collection.key,
|
|
7536
|
+
...operationInfo
|
|
7537
|
+
}, _SIGNAL);
|
|
7538
|
+
}
|
|
7539
|
+
function mutateReplaceRelatedRecord(collection, operationInfo, _SIGNAL) {
|
|
7540
|
+
mutate(collection, {
|
|
7541
|
+
op: 'replaceRelatedRecord',
|
|
7542
|
+
record: collection.identifier,
|
|
7543
|
+
field: collection.key,
|
|
7544
|
+
...operationInfo
|
|
7545
|
+
}, _SIGNAL);
|
|
7546
|
+
}
|
|
7547
|
+
function mutateReplaceRelatedRecords(collection, value, _SIGNAL) {
|
|
7548
|
+
mutate(collection, {
|
|
7549
|
+
op: 'replaceRelatedRecords',
|
|
7550
|
+
record: collection.identifier,
|
|
7551
|
+
field: collection.key,
|
|
7552
|
+
value
|
|
7553
|
+
}, _SIGNAL);
|
|
7554
|
+
}
|
|
7555
|
+
function mutateSortRelatedRecords(collection, value, _SIGNAL) {
|
|
7556
|
+
mutate(collection, {
|
|
7557
|
+
op: 'sortRelatedRecords',
|
|
7558
|
+
record: collection.identifier,
|
|
7559
|
+
field: collection.key,
|
|
7560
|
+
value
|
|
7561
|
+
}, _SIGNAL);
|
|
7562
|
+
}
|
|
7563
|
+
function mutate(collection, mutation, _SIGNAL) {
|
|
7564
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
7565
|
+
if (!test) {
|
|
7566
|
+
throw new Error(`Expected the manager for ManyArray to implement mutate`);
|
|
7567
|
+
}
|
|
7568
|
+
})(typeof collection._manager.mutate === 'function') : {};
|
|
7569
|
+
collection._manager.mutate(mutation);
|
|
7570
|
+
addToTransaction(_SIGNAL);
|
|
7571
|
+
}
|
|
7572
|
+
|
|
7573
|
+
/**
|
|
7574
|
+
@module @ember-data/store
|
|
7575
|
+
*/
|
|
7576
|
+
|
|
6885
7577
|
/**
|
|
6886
7578
|
This method normalizes a modelName into the format EmberData uses
|
|
6887
7579
|
internally by dasherizing it.
|
|
@@ -6909,4 +7601,4 @@ function normalizeModelName(modelName) {
|
|
|
6909
7601
|
}
|
|
6910
7602
|
assert(`normalizeModelName support has been removed`);
|
|
6911
7603
|
}
|
|
6912
|
-
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 };
|
|
7604
|
+
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 };
|