@ember-data/store 5.4.0-beta.15 → 5.4.0-beta.17
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.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{handler-DX830Swd.js → many-array-D-iDvWAq.js} +954 -157
- package/dist/many-array-D-iDvWAq.js.map +1 -0
- 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 +24 -43
- 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 +4 -4
- 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 +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/-types/q/schema-service.d.ts +4 -4
- package/unstable-preview-types/-types/q/schema-service.d.ts.map +1 -1
- package/unstable-preview-types/index.d.ts +22 -20
- package/dist/handler-DX830Swd.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,11 +1,12 @@
|
|
|
1
1
|
import { deprecate, warn } from '@ember/debug';
|
|
2
2
|
import { macroCondition, getGlobalConfig, dependencySatisfies, importSync } from '@embroider/macros';
|
|
3
|
+
import { setLogging, getRuntimeConfig } from '@warp-drive/build-config/runtime';
|
|
3
4
|
import { EnableHydration, SkipCache } from '@warp-drive/core-types/request';
|
|
4
|
-
import { getOrSetGlobal,
|
|
5
|
-
import { CACHE_OWNER, DEBUG_STALE_CACHE_OWNER, DEBUG_CLIENT_ORIGINATED, DEBUG_IDENTIFIER_BUCKET } from '@warp-drive/core-types/identifier';
|
|
6
|
-
import { dasherize } from '@ember-data/request-utils/string';
|
|
7
|
-
import { defineSignal, createSignal, subscribe, createArrayTags, addToTransaction, addTransactionCB } from '@ember-data/tracking/-private';
|
|
5
|
+
import { getOrSetGlobal, peekTransient, setTransient } from '@warp-drive/core-types/-private';
|
|
8
6
|
import { _backburner } from '@ember/runloop';
|
|
7
|
+
import { defineSignal, createSignal, subscribe, createArrayTags, addToTransaction, addTransactionCB } from '@ember-data/tracking/-private';
|
|
8
|
+
import { CACHE_OWNER, DEBUG_STALE_CACHE_OWNER, DEBUG_IDENTIFIER_BUCKET, DEBUG_CLIENT_ORIGINATED } from '@warp-drive/core-types/identifier';
|
|
9
|
+
import { dasherize } from '@ember-data/request-utils/string';
|
|
9
10
|
import { compat } from '@ember-data/tracking';
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -129,10 +130,9 @@ function hasType(resource) {
|
|
|
129
130
|
/**
|
|
130
131
|
@module @ember-data/store
|
|
131
132
|
*/
|
|
132
|
-
const IDENTIFIERS = getOrSetGlobal('IDENTIFIERS', new Set());
|
|
133
133
|
const DOCUMENTS = getOrSetGlobal('DOCUMENTS', new Set());
|
|
134
134
|
function isStableIdentifier(identifier) {
|
|
135
|
-
return identifier[CACHE_OWNER] !== undefined
|
|
135
|
+
return identifier[CACHE_OWNER] !== undefined;
|
|
136
136
|
}
|
|
137
137
|
function isDocumentIdentifier(identifier) {
|
|
138
138
|
return DOCUMENTS.has(identifier);
|
|
@@ -310,9 +310,11 @@ class IdentifierCache {
|
|
|
310
310
|
*/
|
|
311
311
|
|
|
312
312
|
_getRecordIdentifier(resource, shouldGenerate) {
|
|
313
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
314
|
-
|
|
315
|
-
|
|
313
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
314
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
315
|
+
// eslint-disable-next-line no-console
|
|
316
|
+
console.groupCollapsed(`Identifiers: ${shouldGenerate ? 'Generating' : 'Peeking'} Identifier`, resource);
|
|
317
|
+
}
|
|
316
318
|
}
|
|
317
319
|
// short circuit if we're already the stable version
|
|
318
320
|
if (isStableIdentifier(resource)) {
|
|
@@ -322,33 +324,41 @@ class IdentifierCache {
|
|
|
322
324
|
throw new Error(`The supplied identifier ${JSON.stringify(resource)} does not belong to this store instance`);
|
|
323
325
|
}
|
|
324
326
|
}
|
|
325
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
327
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
328
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
329
|
+
// eslint-disable-next-line no-console
|
|
330
|
+
console.log(`Identifiers: cache HIT - Stable ${resource.lid}`);
|
|
331
|
+
// eslint-disable-next-line no-console
|
|
332
|
+
console.groupEnd();
|
|
333
|
+
}
|
|
330
334
|
}
|
|
331
335
|
return resource;
|
|
332
336
|
}
|
|
333
337
|
|
|
334
338
|
// the resource is unknown, ask the application to identify this data for us
|
|
335
339
|
const lid = this._generate(resource, 'record');
|
|
336
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
337
|
-
|
|
338
|
-
|
|
340
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
341
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
342
|
+
// eslint-disable-next-line no-console
|
|
343
|
+
console.log(`Identifiers: ${lid ? 'no ' : ''}lid ${lid ? lid + ' ' : ''}determined for resource`, resource);
|
|
344
|
+
}
|
|
339
345
|
}
|
|
340
346
|
let identifier = /*#__NOINLINE__*/getIdentifierFromLid(this._cache, lid, resource);
|
|
341
347
|
if (identifier !== null) {
|
|
342
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
343
|
-
|
|
344
|
-
|
|
348
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
349
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
350
|
+
// eslint-disable-next-line no-console
|
|
351
|
+
console.groupEnd();
|
|
352
|
+
}
|
|
345
353
|
}
|
|
346
354
|
return identifier;
|
|
347
355
|
}
|
|
348
356
|
if (shouldGenerate === 0) {
|
|
349
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
350
|
-
|
|
351
|
-
|
|
357
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
358
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
359
|
+
// eslint-disable-next-line no-console
|
|
360
|
+
console.groupEnd();
|
|
361
|
+
}
|
|
352
362
|
}
|
|
353
363
|
return;
|
|
354
364
|
}
|
|
@@ -366,9 +376,11 @@ class IdentifierCache {
|
|
|
366
376
|
identifier = /*#__NOINLINE__*/makeStableRecordIdentifier(keyInfo, 'record', false);
|
|
367
377
|
}
|
|
368
378
|
addResourceToCache(this._cache, identifier);
|
|
369
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
370
|
-
|
|
371
|
-
|
|
379
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
380
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
381
|
+
// eslint-disable-next-line no-console
|
|
382
|
+
console.groupEnd();
|
|
383
|
+
}
|
|
372
384
|
}
|
|
373
385
|
return identifier;
|
|
374
386
|
}
|
|
@@ -462,9 +474,11 @@ class IdentifierCache {
|
|
|
462
474
|
|
|
463
475
|
/*#__NOINLINE__*/
|
|
464
476
|
addResourceToCache(this._cache, identifier);
|
|
465
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
466
|
-
|
|
467
|
-
|
|
477
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
478
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
479
|
+
// eslint-disable-next-line no-console
|
|
480
|
+
console.log(`Identifiers: created identifier ${String(identifier)} for newly generated resource`, data);
|
|
481
|
+
}
|
|
468
482
|
}
|
|
469
483
|
return identifier;
|
|
470
484
|
}
|
|
@@ -511,9 +525,11 @@ class IdentifierCache {
|
|
|
511
525
|
if (hadLid) {
|
|
512
526
|
data.lid = identifier.lid;
|
|
513
527
|
}
|
|
514
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
515
|
-
|
|
516
|
-
|
|
528
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
529
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
530
|
+
// eslint-disable-next-line no-console
|
|
531
|
+
console.log(`Identifiers: merged identifiers ${generatedIdentifier.lid} and ${existingIdentifier.lid} for resource into ${identifier.lid}`, data);
|
|
532
|
+
}
|
|
517
533
|
}
|
|
518
534
|
}
|
|
519
535
|
const id = identifier.id;
|
|
@@ -523,9 +539,11 @@ class IdentifierCache {
|
|
|
523
539
|
|
|
524
540
|
// add to our own secondary lookup table
|
|
525
541
|
if (id !== newId && newId !== null) {
|
|
526
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
527
|
-
|
|
528
|
-
|
|
542
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
543
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
544
|
+
// eslint-disable-next-line no-console
|
|
545
|
+
console.log(`Identifiers: updated id for identifier ${identifier.lid} from '${String(id)}' to '${String(newId)}' for resource`, data);
|
|
546
|
+
}
|
|
529
547
|
}
|
|
530
548
|
const typeSet = this._cache.resourcesByType[identifier.type];
|
|
531
549
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
@@ -537,9 +555,11 @@ class IdentifierCache {
|
|
|
537
555
|
if (id !== null) {
|
|
538
556
|
typeSet.id.delete(id);
|
|
539
557
|
}
|
|
540
|
-
} else if (macroCondition(getGlobalConfig().WarpDrive.
|
|
541
|
-
|
|
542
|
-
|
|
558
|
+
} else if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
559
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
560
|
+
// eslint-disable-next-line no-console
|
|
561
|
+
console.log(`Identifiers: updated identifier ${identifier.lid} resource`, data);
|
|
562
|
+
}
|
|
543
563
|
}
|
|
544
564
|
return identifier;
|
|
545
565
|
}
|
|
@@ -621,11 +641,12 @@ class IdentifierCache {
|
|
|
621
641
|
identifier[DEBUG_STALE_CACHE_OWNER] = identifier[CACHE_OWNER];
|
|
622
642
|
}
|
|
623
643
|
identifier[CACHE_OWNER] = undefined;
|
|
624
|
-
IDENTIFIERS.delete(identifier);
|
|
625
644
|
this._forget(identifier, 'record');
|
|
626
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
627
|
-
|
|
628
|
-
|
|
645
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
646
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
647
|
+
// eslint-disable-next-line no-console
|
|
648
|
+
console.log(`Identifiers: released identifier ${identifierObject.lid}`);
|
|
649
|
+
}
|
|
629
650
|
}
|
|
630
651
|
}
|
|
631
652
|
destroy() {
|
|
@@ -637,20 +658,17 @@ class IdentifierCache {
|
|
|
637
658
|
}
|
|
638
659
|
}
|
|
639
660
|
function makeStableRecordIdentifier(recordIdentifier, bucket, clientOriginated) {
|
|
640
|
-
IDENTIFIERS.add(recordIdentifier);
|
|
641
661
|
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
642
662
|
// we enforce immutability in dev
|
|
643
663
|
// but preserve our ability to do controlled updates to the reference
|
|
644
664
|
let wrapper = {
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
},
|
|
665
|
+
type: recordIdentifier.type,
|
|
666
|
+
lid: recordIdentifier.lid,
|
|
648
667
|
get id() {
|
|
649
668
|
return recordIdentifier.id;
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
},
|
|
669
|
+
}
|
|
670
|
+
};
|
|
671
|
+
const proto = {
|
|
654
672
|
get [CACHE_OWNER]() {
|
|
655
673
|
return recordIdentifier[CACHE_OWNER];
|
|
656
674
|
},
|
|
@@ -662,9 +680,15 @@ function makeStableRecordIdentifier(recordIdentifier, bucket, clientOriginated)
|
|
|
662
680
|
},
|
|
663
681
|
set [DEBUG_STALE_CACHE_OWNER](value) {
|
|
664
682
|
recordIdentifier[DEBUG_STALE_CACHE_OWNER] = value;
|
|
683
|
+
},
|
|
684
|
+
get [DEBUG_CLIENT_ORIGINATED]() {
|
|
685
|
+
return clientOriginated;
|
|
686
|
+
},
|
|
687
|
+
get [DEBUG_IDENTIFIER_BUCKET]() {
|
|
688
|
+
return bucket;
|
|
665
689
|
}
|
|
666
690
|
};
|
|
667
|
-
Object.defineProperty(
|
|
691
|
+
Object.defineProperty(proto, 'toString', {
|
|
668
692
|
enumerable: false,
|
|
669
693
|
value: () => {
|
|
670
694
|
const {
|
|
@@ -675,7 +699,7 @@ function makeStableRecordIdentifier(recordIdentifier, bucket, clientOriginated)
|
|
|
675
699
|
return `${clientOriginated ? '[CLIENT_ORIGINATED] ' : ''}${String(type)}:${String(id)} (${lid})`;
|
|
676
700
|
}
|
|
677
701
|
});
|
|
678
|
-
Object.defineProperty(
|
|
702
|
+
Object.defineProperty(proto, 'toJSON', {
|
|
679
703
|
enumerable: false,
|
|
680
704
|
value: () => {
|
|
681
705
|
const {
|
|
@@ -690,9 +714,7 @@ function makeStableRecordIdentifier(recordIdentifier, bucket, clientOriginated)
|
|
|
690
714
|
};
|
|
691
715
|
}
|
|
692
716
|
});
|
|
693
|
-
wrapper
|
|
694
|
-
wrapper[DEBUG_IDENTIFIER_BUCKET] = bucket;
|
|
695
|
-
IDENTIFIERS.add(wrapper);
|
|
717
|
+
Object.setPrototypeOf(wrapper, proto);
|
|
696
718
|
DEBUG_MAP.set(wrapper, recordIdentifier);
|
|
697
719
|
wrapper = freeze(wrapper);
|
|
698
720
|
return wrapper;
|
|
@@ -775,9 +797,11 @@ function detectMerge(cache, keyInfo, identifier, data) {
|
|
|
775
797
|
}
|
|
776
798
|
function getIdentifierFromLid(cache, lid, resource) {
|
|
777
799
|
const identifier = cache.resources.get(lid);
|
|
778
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
779
|
-
|
|
780
|
-
|
|
800
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
|
|
801
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
|
|
802
|
+
// eslint-disable-next-line no-console
|
|
803
|
+
console.log(`Identifiers: cache ${identifier ? 'HIT' : 'MISS'} - Non-Stable ${lid}`, resource);
|
|
804
|
+
}
|
|
781
805
|
}
|
|
782
806
|
return identifier || null;
|
|
783
807
|
}
|
|
@@ -796,6 +820,87 @@ function addResourceToCache(cache, identifier) {
|
|
|
796
820
|
typeSet.id.set(identifier.id, identifier);
|
|
797
821
|
}
|
|
798
822
|
}
|
|
823
|
+
const TEXT_COLORS = {
|
|
824
|
+
TEXT: 'inherit',
|
|
825
|
+
notify: ['white', 'white', 'inherit', 'magenta', 'inherit'],
|
|
826
|
+
'reactive-ui': ['white', 'white', 'inherit', 'magenta', 'inherit'],
|
|
827
|
+
graph: ['white', 'white', 'inherit', 'magenta', 'inherit'],
|
|
828
|
+
request: ['white', 'white', 'inherit', 'magenta', 'inherit'],
|
|
829
|
+
cache: ['white', 'white', 'inherit', 'magenta', 'inherit']
|
|
830
|
+
};
|
|
831
|
+
const BG_COLORS = {
|
|
832
|
+
TEXT: 'transparent',
|
|
833
|
+
notify: ['dimgray', 'cadetblue', 'transparent', 'transparent', 'transparent'],
|
|
834
|
+
'reactive-ui': ['dimgray', 'cadetblue', 'transparent', 'transparent', 'transparent'],
|
|
835
|
+
graph: ['dimgray', 'cadetblue', 'transparent', 'transparent', 'transparent'],
|
|
836
|
+
request: ['dimgray', 'cadetblue', 'transparent', 'transparent', 'transparent'],
|
|
837
|
+
cache: ['dimgray', 'cadetblue', 'transparent', 'transparent', 'transparent']
|
|
838
|
+
};
|
|
839
|
+
const NOTIFY_BORDER = {
|
|
840
|
+
TEXT: 0,
|
|
841
|
+
notify: [3, 2, 0, 0, 0],
|
|
842
|
+
'reactive-ui': [3, 2, 0, 0, 0],
|
|
843
|
+
graph: [3, 2, 0, 0, 0],
|
|
844
|
+
request: [3, 2, 0, 0, 0],
|
|
845
|
+
cache: [3, 2, 0, 0, 0]
|
|
846
|
+
};
|
|
847
|
+
const LIGHT_DARK_ALT = {
|
|
848
|
+
lightgreen: 'green',
|
|
849
|
+
green: 'lightgreen'
|
|
850
|
+
};
|
|
851
|
+
function badge(isLight, color, bgColor, border) {
|
|
852
|
+
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};`];
|
|
853
|
+
}
|
|
854
|
+
function colorForBucket(isLight, scope, bucket) {
|
|
855
|
+
if (scope === 'notify') {
|
|
856
|
+
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]);
|
|
857
|
+
}
|
|
858
|
+
if (scope === 'reactive-ui') {
|
|
859
|
+
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]);
|
|
860
|
+
}
|
|
861
|
+
if (scope === 'cache') {
|
|
862
|
+
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]);
|
|
863
|
+
}
|
|
864
|
+
return badge(isLight, TEXT_COLORS[scope][3], BG_COLORS[scope][3], NOTIFY_BORDER[scope][3]);
|
|
865
|
+
}
|
|
866
|
+
function logGroup(scope, prefix, subScop1, subScop2, subScop3, subScop4) {
|
|
867
|
+
// eslint-disable-next-line no-console
|
|
868
|
+
console.groupCollapsed(..._log(scope, prefix, subScop1, subScop2, subScop3, subScop4));
|
|
869
|
+
}
|
|
870
|
+
function log(scope, prefix, subScop1, subScop2, subScop3, subScop4) {
|
|
871
|
+
// eslint-disable-next-line no-console
|
|
872
|
+
console.log(..._log(scope, prefix, subScop1, subScop2, subScop3, subScop4));
|
|
873
|
+
}
|
|
874
|
+
function correctColor(isLight, color) {
|
|
875
|
+
if (!isLight) {
|
|
876
|
+
return color;
|
|
877
|
+
}
|
|
878
|
+
return color in LIGHT_DARK_ALT ? LIGHT_DARK_ALT[color] : color;
|
|
879
|
+
}
|
|
880
|
+
function isLightMode() {
|
|
881
|
+
if (window?.matchMedia?.('(prefers-color-scheme: light)').matches) {
|
|
882
|
+
return true;
|
|
883
|
+
}
|
|
884
|
+
return false;
|
|
885
|
+
}
|
|
886
|
+
function _log(scope, prefix, subScop1, subScop2, subScop3, subScop4) {
|
|
887
|
+
const isLight = isLightMode();
|
|
888
|
+
switch (scope) {
|
|
889
|
+
case 'reactive-ui':
|
|
890
|
+
case 'notify':
|
|
891
|
+
{
|
|
892
|
+
const scopePath = prefix ? `[${prefix}] ${scope}` : scope;
|
|
893
|
+
const path = subScop4 ? `${subScop3}.${subScop4}` : subScop3;
|
|
894
|
+
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)];
|
|
895
|
+
}
|
|
896
|
+
case 'cache':
|
|
897
|
+
{
|
|
898
|
+
const scopePath = prefix ? `${scope} (${prefix})` : scope;
|
|
899
|
+
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])];
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
return [];
|
|
903
|
+
}
|
|
799
904
|
|
|
800
905
|
/**
|
|
801
906
|
@module @ember-data/store
|
|
@@ -1252,9 +1357,16 @@ class InstanceCache {
|
|
|
1252
1357
|
setCacheFor(record, cache);
|
|
1253
1358
|
StoreMap.set(record, this.store);
|
|
1254
1359
|
this.__instances.record.set(identifier, record);
|
|
1255
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1256
|
-
|
|
1257
|
-
|
|
1360
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1361
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1362
|
+
logGroup('reactive-ui', '', identifier.type, identifier.lid, 'created', '');
|
|
1363
|
+
// eslint-disable-next-line no-console
|
|
1364
|
+
console.log({
|
|
1365
|
+
properties
|
|
1366
|
+
});
|
|
1367
|
+
// eslint-disable-next-line no-console
|
|
1368
|
+
console.groupEnd();
|
|
1369
|
+
}
|
|
1258
1370
|
}
|
|
1259
1371
|
}
|
|
1260
1372
|
return record;
|
|
@@ -1300,9 +1412,10 @@ class InstanceCache {
|
|
|
1300
1412
|
this.store.identifierCache.forgetRecordIdentifier(identifier);
|
|
1301
1413
|
removeRecordDataFor(identifier);
|
|
1302
1414
|
this.store._requestCache._clearEntries(identifier);
|
|
1303
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1304
|
-
|
|
1305
|
-
|
|
1415
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1416
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1417
|
+
log('reactive-ui', '', identifier.type, identifier.lid, 'disconnected', '');
|
|
1418
|
+
}
|
|
1306
1419
|
}
|
|
1307
1420
|
}
|
|
1308
1421
|
unloadRecord(identifier) {
|
|
@@ -1318,9 +1431,11 @@ class InstanceCache {
|
|
|
1318
1431
|
})() : {};
|
|
1319
1432
|
}
|
|
1320
1433
|
}
|
|
1321
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1322
|
-
|
|
1323
|
-
|
|
1434
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1435
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1436
|
+
// eslint-disable-next-line no-console
|
|
1437
|
+
console.groupCollapsed(`InstanceCache: unloading record for ${String(identifier)}`);
|
|
1438
|
+
}
|
|
1324
1439
|
}
|
|
1325
1440
|
|
|
1326
1441
|
// TODO is this join still necessary?
|
|
@@ -1333,27 +1448,33 @@ class InstanceCache {
|
|
|
1333
1448
|
StoreMap.delete(record);
|
|
1334
1449
|
RecordCache.delete(record);
|
|
1335
1450
|
removeRecordDataFor(record);
|
|
1336
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1337
|
-
|
|
1338
|
-
|
|
1451
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1452
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1453
|
+
// eslint-disable-next-line no-console
|
|
1454
|
+
console.log(`InstanceCache: destroyed record for ${String(identifier)}`);
|
|
1455
|
+
}
|
|
1339
1456
|
}
|
|
1340
1457
|
}
|
|
1341
1458
|
if (cache) {
|
|
1342
1459
|
cache.unloadRecord(identifier);
|
|
1343
1460
|
removeRecordDataFor(identifier);
|
|
1344
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1345
|
-
|
|
1346
|
-
|
|
1461
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1462
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1463
|
+
// eslint-disable-next-line no-console
|
|
1464
|
+
console.log(`InstanceCache: destroyed cache for ${String(identifier)}`);
|
|
1465
|
+
}
|
|
1347
1466
|
}
|
|
1348
1467
|
} else {
|
|
1349
1468
|
this.disconnect(identifier);
|
|
1350
1469
|
}
|
|
1351
1470
|
this.store._requestCache._clearEntries(identifier);
|
|
1352
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1471
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1472
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1473
|
+
// eslint-disable-next-line no-console
|
|
1474
|
+
console.log(`InstanceCache: unloaded RecordData for ${String(identifier)}`);
|
|
1475
|
+
// eslint-disable-next-line no-console
|
|
1476
|
+
console.groupEnd();
|
|
1477
|
+
}
|
|
1357
1478
|
}
|
|
1358
1479
|
});
|
|
1359
1480
|
}
|
|
@@ -1408,9 +1529,11 @@ class InstanceCache {
|
|
|
1408
1529
|
warn(`Your ${type} record was saved to the server, but the response does not have an id.`, !(oldId !== null && id === null));
|
|
1409
1530
|
return;
|
|
1410
1531
|
}
|
|
1411
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
1412
|
-
|
|
1413
|
-
|
|
1532
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
|
|
1533
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
|
|
1534
|
+
// eslint-disable-next-line no-console
|
|
1535
|
+
console.log(`InstanceCache: updating id to '${id}' for record ${String(identifier)}`);
|
|
1536
|
+
}
|
|
1414
1537
|
}
|
|
1415
1538
|
const existingIdentifier = this.store.identifierCache.peekRecordIdentifier({
|
|
1416
1539
|
type,
|
|
@@ -1727,7 +1850,9 @@ class CacheManager {
|
|
|
1727
1850
|
peek(identifier) {
|
|
1728
1851
|
return this.#cache.peek(identifier);
|
|
1729
1852
|
}
|
|
1730
|
-
|
|
1853
|
+
peekRemoteState(identifier) {
|
|
1854
|
+
return this.#cache.peekRemoteState(identifier);
|
|
1855
|
+
}
|
|
1731
1856
|
/**
|
|
1732
1857
|
* Peek the Cache for the existing request data associated with
|
|
1733
1858
|
* a cacheable request
|
|
@@ -1950,6 +2075,19 @@ class CacheManager {
|
|
|
1950
2075
|
return this.#cache.getAttr(identifier, propertyName);
|
|
1951
2076
|
}
|
|
1952
2077
|
|
|
2078
|
+
/**
|
|
2079
|
+
* Retrieve the remote state for an attribute from the cache
|
|
2080
|
+
*
|
|
2081
|
+
* @method getRemoteAttr
|
|
2082
|
+
* @public
|
|
2083
|
+
* @param identifier
|
|
2084
|
+
* @param propertyName
|
|
2085
|
+
* @return {unknown}
|
|
2086
|
+
*/
|
|
2087
|
+
getRemoteAttr(identifier, propertyName) {
|
|
2088
|
+
return this.#cache.getRemoteAttr(identifier, propertyName);
|
|
2089
|
+
}
|
|
2090
|
+
|
|
1953
2091
|
/**
|
|
1954
2092
|
* Mutate the data for an attribute in the cache
|
|
1955
2093
|
*
|
|
@@ -2074,6 +2212,19 @@ class CacheManager {
|
|
|
2074
2212
|
return this.#cache.getRelationship(identifier, propertyName);
|
|
2075
2213
|
}
|
|
2076
2214
|
|
|
2215
|
+
/**
|
|
2216
|
+
* Query the cache for the remote state of a relationship property
|
|
2217
|
+
*
|
|
2218
|
+
* @method getRelationship
|
|
2219
|
+
* @public
|
|
2220
|
+
* @param identifier
|
|
2221
|
+
* @param propertyName
|
|
2222
|
+
* @return resource relationship object
|
|
2223
|
+
*/
|
|
2224
|
+
getRemoteRelationship(identifier, propertyName) {
|
|
2225
|
+
return this.#cache.getRemoteRelationship(identifier, propertyName);
|
|
2226
|
+
}
|
|
2227
|
+
|
|
2077
2228
|
// Resource State
|
|
2078
2229
|
// ===============
|
|
2079
2230
|
|
|
@@ -2158,27 +2309,51 @@ class CacheManager {
|
|
|
2158
2309
|
* @module @ember-data/store
|
|
2159
2310
|
*/
|
|
2160
2311
|
|
|
2161
|
-
let tokenId = 0;
|
|
2162
|
-
const CacheOperations = new Set(['added', 'removed', 'state', 'updated', 'invalidated']);
|
|
2163
2312
|
function isCacheOperationValue(value) {
|
|
2164
|
-
return
|
|
2313
|
+
return value === 'added' || value === 'state' || value === 'updated' || value === 'removed' || value === 'invalidated';
|
|
2165
2314
|
}
|
|
2166
2315
|
function runLoopIsFlushing() {
|
|
2167
2316
|
//@ts-expect-error
|
|
2168
2317
|
return !!_backburner.currentInstance && _backburner._autorun !== true;
|
|
2169
2318
|
}
|
|
2170
|
-
function
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2319
|
+
function count(label) {
|
|
2320
|
+
// @ts-expect-error
|
|
2321
|
+
// eslint-disable-next-line
|
|
2322
|
+
globalThis.__WarpDriveMetricCountData[label] = (globalThis.__WarpDriveMetricCountData[label] || 0) + 1;
|
|
2323
|
+
}
|
|
2324
|
+
function asInternalToken(token) {
|
|
2325
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2326
|
+
if (!test) {
|
|
2327
|
+
throw new Error(`Expected a token with a 'for' property`);
|
|
2328
|
+
}
|
|
2329
|
+
})(token && typeof token === 'function' && 'for' in token) : {};
|
|
2330
|
+
}
|
|
2331
|
+
function _unsubscribe(token, cache) {
|
|
2332
|
+
asInternalToken(token);
|
|
2333
|
+
const identifier = token.for;
|
|
2334
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
|
|
2335
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
|
|
2336
|
+
if (!identifier) {
|
|
2337
|
+
// eslint-disable-next-line no-console
|
|
2338
|
+
console.log('Passed unknown unsubscribe token to unsubscribe', identifier);
|
|
2339
|
+
}
|
|
2176
2340
|
}
|
|
2177
2341
|
}
|
|
2178
2342
|
if (identifier) {
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2343
|
+
const callbacks = cache.get(identifier);
|
|
2344
|
+
if (!callbacks) {
|
|
2345
|
+
return;
|
|
2346
|
+
}
|
|
2347
|
+
const index = callbacks.indexOf(token);
|
|
2348
|
+
if (index === -1) {
|
|
2349
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2350
|
+
if (!test) {
|
|
2351
|
+
throw new Error(`Cannot unsubscribe a token that is not subscribed`);
|
|
2352
|
+
}
|
|
2353
|
+
})(index !== -1) : {};
|
|
2354
|
+
return;
|
|
2355
|
+
}
|
|
2356
|
+
callbacks.splice(index, 1);
|
|
2182
2357
|
}
|
|
2183
2358
|
}
|
|
2184
2359
|
|
|
@@ -2199,7 +2374,6 @@ class NotificationManager {
|
|
|
2199
2374
|
this._buffered = new Map();
|
|
2200
2375
|
this._hasFlush = false;
|
|
2201
2376
|
this._cache = new Map();
|
|
2202
|
-
this._tokens = new Map();
|
|
2203
2377
|
}
|
|
2204
2378
|
|
|
2205
2379
|
/**
|
|
@@ -2236,17 +2410,26 @@ class NotificationManager {
|
|
|
2236
2410
|
throw new Error(`Expected to receive a stable Identifier to subscribe to`);
|
|
2237
2411
|
}
|
|
2238
2412
|
})(identifier === 'resource' || identifier === 'document' || isStableIdentifier(identifier) || isDocumentIdentifier(identifier)) : {};
|
|
2239
|
-
let
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2413
|
+
let callbacks = this._cache.get(identifier);
|
|
2414
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2415
|
+
if (!test) {
|
|
2416
|
+
throw new Error(`expected to receive a valid callback`);
|
|
2417
|
+
}
|
|
2418
|
+
})(typeof callback === 'function') : {};
|
|
2419
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2420
|
+
if (!test) {
|
|
2421
|
+
throw new Error(`cannot subscribe with the same callback twice`);
|
|
2422
|
+
}
|
|
2423
|
+
})(!callbacks || !callbacks.includes(callback)) : {};
|
|
2424
|
+
// we use the callback as the cancellation token
|
|
2425
|
+
//@ts-expect-error
|
|
2426
|
+
callback.for = identifier;
|
|
2427
|
+
if (!callbacks) {
|
|
2428
|
+
callbacks = [];
|
|
2429
|
+
this._cache.set(identifier, callbacks);
|
|
2243
2430
|
}
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
} : {};
|
|
2247
|
-
map.set(unsubToken, callback);
|
|
2248
|
-
this._tokens.set(unsubToken, identifier);
|
|
2249
|
-
return unsubToken;
|
|
2431
|
+
callbacks.push(callback);
|
|
2432
|
+
return callback;
|
|
2250
2433
|
}
|
|
2251
2434
|
|
|
2252
2435
|
/**
|
|
@@ -2258,7 +2441,7 @@ class NotificationManager {
|
|
|
2258
2441
|
*/
|
|
2259
2442
|
unsubscribe(token) {
|
|
2260
2443
|
if (!this.isDestroyed) {
|
|
2261
|
-
_unsubscribe(
|
|
2444
|
+
_unsubscribe(token, this._cache);
|
|
2262
2445
|
}
|
|
2263
2446
|
}
|
|
2264
2447
|
|
|
@@ -2280,17 +2463,15 @@ class NotificationManager {
|
|
|
2280
2463
|
}
|
|
2281
2464
|
})(!key || value === 'attributes' || value === 'relationships') : {};
|
|
2282
2465
|
if (!isStableIdentifier(identifier) && !isDocumentIdentifier(identifier)) {
|
|
2283
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
2284
|
-
|
|
2285
|
-
|
|
2466
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
|
|
2467
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
|
|
2468
|
+
// eslint-disable-next-line no-console
|
|
2469
|
+
console.log(`Notifying: Expected to receive a stable Identifier to notify '${value}' '${key || ''}' with, but ${String(identifier)} is not in the cache`, identifier);
|
|
2470
|
+
}
|
|
2286
2471
|
}
|
|
2287
2472
|
return false;
|
|
2288
2473
|
}
|
|
2289
|
-
|
|
2290
|
-
// eslint-disable-next-line no-console
|
|
2291
|
-
console.log(`Buffering Notify: ${String(identifier.lid)}\t${value}\t${key || ''}`);
|
|
2292
|
-
}
|
|
2293
|
-
const hasSubscribers = Boolean(this._cache.get(identifier)?.size);
|
|
2474
|
+
const hasSubscribers = Boolean(this._cache.get(identifier)?.length);
|
|
2294
2475
|
if (isCacheOperationValue(value) || hasSubscribers) {
|
|
2295
2476
|
let buffer = this._buffered.get(identifier);
|
|
2296
2477
|
if (!buffer) {
|
|
@@ -2298,7 +2479,22 @@ class NotificationManager {
|
|
|
2298
2479
|
this._buffered.set(identifier, buffer);
|
|
2299
2480
|
}
|
|
2300
2481
|
buffer.push([value, key]);
|
|
2301
|
-
|
|
2482
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
|
|
2483
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
|
|
2484
|
+
count(`notify ${'type' in identifier ? identifier.type : '<document>'} ${value} ${key}`);
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
if (!this._scheduleNotify()) {
|
|
2488
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
|
|
2489
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
|
|
2490
|
+
log('notify', 'buffered', `${'type' in identifier ? identifier.type : 'document'}`, identifier.lid, `${value}`, key || '');
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
} else if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
|
|
2495
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
|
|
2496
|
+
count(`DISCARDED notify ${'type' in identifier ? identifier.type : '<document>'} ${value} ${key}`);
|
|
2497
|
+
}
|
|
2302
2498
|
}
|
|
2303
2499
|
return hasSubscribers;
|
|
2304
2500
|
}
|
|
@@ -2309,14 +2505,15 @@ class NotificationManager {
|
|
|
2309
2505
|
const asyncFlush = this.store._enableAsyncFlush;
|
|
2310
2506
|
if (this._hasFlush) {
|
|
2311
2507
|
if (asyncFlush !== false && !runLoopIsFlushing()) {
|
|
2312
|
-
return;
|
|
2508
|
+
return false;
|
|
2313
2509
|
}
|
|
2314
2510
|
}
|
|
2315
2511
|
if (asyncFlush && !runLoopIsFlushing()) {
|
|
2316
2512
|
this._hasFlush = true;
|
|
2317
|
-
return;
|
|
2513
|
+
return false;
|
|
2318
2514
|
}
|
|
2319
2515
|
this._flush();
|
|
2516
|
+
return true;
|
|
2320
2517
|
}
|
|
2321
2518
|
_flush() {
|
|
2322
2519
|
const buffered = this._buffered;
|
|
@@ -2334,9 +2531,10 @@ class NotificationManager {
|
|
|
2334
2531
|
this._onFlushCB = undefined;
|
|
2335
2532
|
}
|
|
2336
2533
|
_flushNotification(identifier, value, key) {
|
|
2337
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
2338
|
-
|
|
2339
|
-
|
|
2534
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
|
|
2535
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
|
|
2536
|
+
log('notify', '', `${'type' in identifier ? identifier.type : 'document'}`, identifier.lid, `${value}`, key || '');
|
|
2537
|
+
}
|
|
2340
2538
|
}
|
|
2341
2539
|
|
|
2342
2540
|
// TODO for documents this will need to switch based on Identifier kind
|
|
@@ -2348,11 +2546,11 @@ class NotificationManager {
|
|
|
2348
2546
|
});
|
|
2349
2547
|
}
|
|
2350
2548
|
}
|
|
2351
|
-
const
|
|
2352
|
-
if (!
|
|
2549
|
+
const callbacks = this._cache.get(identifier);
|
|
2550
|
+
if (!callbacks || !callbacks.length) {
|
|
2353
2551
|
return false;
|
|
2354
2552
|
}
|
|
2355
|
-
|
|
2553
|
+
callbacks.forEach(cb => {
|
|
2356
2554
|
// @ts-expect-error overload doesn't narrow within body
|
|
2357
2555
|
cb(identifier, value, key);
|
|
2358
2556
|
});
|
|
@@ -2360,7 +2558,6 @@ class NotificationManager {
|
|
|
2360
2558
|
}
|
|
2361
2559
|
destroy() {
|
|
2362
2560
|
this.isDestroyed = true;
|
|
2363
|
-
this._tokens.clear();
|
|
2364
2561
|
this._cache.clear();
|
|
2365
2562
|
}
|
|
2366
2563
|
}
|
|
@@ -2682,7 +2879,7 @@ class IdentifierArray {
|
|
|
2682
2879
|
return false;
|
|
2683
2880
|
}
|
|
2684
2881
|
const original = target[index];
|
|
2685
|
-
const newIdentifier = extractIdentifierFromRecord$
|
|
2882
|
+
const newIdentifier = extractIdentifierFromRecord$2(value);
|
|
2686
2883
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2687
2884
|
if (!test) {
|
|
2688
2885
|
throw new Error(`Expected a record`);
|
|
@@ -2723,9 +2920,18 @@ class IdentifierArray {
|
|
|
2723
2920
|
return Reflect.deleteProperty(target, prop);
|
|
2724
2921
|
},
|
|
2725
2922
|
getPrototypeOf() {
|
|
2726
|
-
return
|
|
2923
|
+
return Array.prototype;
|
|
2727
2924
|
}
|
|
2728
2925
|
});
|
|
2926
|
+
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
2927
|
+
Object.defineProperty(this, '__SHOW_ME_THE_DATA_(debug mode only)__', {
|
|
2928
|
+
enumerable: false,
|
|
2929
|
+
configurable: true,
|
|
2930
|
+
get() {
|
|
2931
|
+
return proxy.slice();
|
|
2932
|
+
}
|
|
2933
|
+
});
|
|
2934
|
+
}
|
|
2729
2935
|
createArrayTags(proxy, _SIGNAL);
|
|
2730
2936
|
this[NOTIFY] = this[NOTIFY].bind(proxy);
|
|
2731
2937
|
return proxy;
|
|
@@ -2866,7 +3072,7 @@ Collection.prototype.query = null;
|
|
|
2866
3072
|
// Ensure instanceof works correctly
|
|
2867
3073
|
// Object.setPrototypeOf(IdentifierArray.prototype, Array.prototype);
|
|
2868
3074
|
|
|
2869
|
-
function assertRecordPassedToHasMany(record) {
|
|
3075
|
+
function assertRecordPassedToHasMany$1(record) {
|
|
2870
3076
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2871
3077
|
if (!test) {
|
|
2872
3078
|
throw new Error(`All elements of a hasMany relationship must be instances of Model, you passed $${typeof record}`);
|
|
@@ -2880,11 +3086,11 @@ function assertRecordPassedToHasMany(record) {
|
|
|
2880
3086
|
}
|
|
2881
3087
|
}()) : {};
|
|
2882
3088
|
}
|
|
2883
|
-
function extractIdentifierFromRecord$
|
|
3089
|
+
function extractIdentifierFromRecord$2(record) {
|
|
2884
3090
|
if (!record) {
|
|
2885
3091
|
return null;
|
|
2886
3092
|
}
|
|
2887
|
-
assertRecordPassedToHasMany(record);
|
|
3093
|
+
assertRecordPassedToHasMany$1(record);
|
|
2888
3094
|
return recordIdentifierFor(record);
|
|
2889
3095
|
}
|
|
2890
3096
|
|
|
@@ -2979,6 +3185,9 @@ class RecordArrayManager {
|
|
|
2979
3185
|
sync(array, pending, this._set.get(array));
|
|
2980
3186
|
this._pending.delete(array);
|
|
2981
3187
|
}
|
|
3188
|
+
mutate(mutation) {
|
|
3189
|
+
this.store.cache.mutate(mutation);
|
|
3190
|
+
}
|
|
2982
3191
|
|
|
2983
3192
|
/**
|
|
2984
3193
|
Get the `RecordArray` for a modelName, which contains all loaded records of
|
|
@@ -3495,6 +3704,118 @@ function constructResource(type, id, lid) {
|
|
|
3495
3704
|
*/
|
|
3496
3705
|
// this import location is deprecated but breaks in 4.8 and older
|
|
3497
3706
|
|
|
3707
|
+
// @ts-expect-error adding to globalThis
|
|
3708
|
+
globalThis.setWarpDriveLogging = setLogging;
|
|
3709
|
+
|
|
3710
|
+
// @ts-expect-error adding to globalThis
|
|
3711
|
+
globalThis.getWarpDriveRuntimeConfig = getRuntimeConfig;
|
|
3712
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
|
|
3713
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
|
|
3714
|
+
// @ts-expect-error adding to globalThis
|
|
3715
|
+
// eslint-disable-next-line
|
|
3716
|
+
globalThis.__WarpDriveMetricCountData = globalThis.__WarpDriveMetricCountData || {};
|
|
3717
|
+
|
|
3718
|
+
// @ts-expect-error adding to globalThis
|
|
3719
|
+
globalThis.getWarpDriveMetricCounts = () => {
|
|
3720
|
+
// @ts-expect-error
|
|
3721
|
+
// eslint-disable-next-line
|
|
3722
|
+
return structuredClone(globalThis.__WarpDriveMetricCountData);
|
|
3723
|
+
};
|
|
3724
|
+
|
|
3725
|
+
// @ts-expect-error adding to globalThis
|
|
3726
|
+
globalThis.resetWarpDriveMetricCounts = () => {
|
|
3727
|
+
// @ts-expect-error
|
|
3728
|
+
globalThis.__WarpDriveMetricCountData = {};
|
|
3729
|
+
};
|
|
3730
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.__INTERNAL_LOG_NATIVE_MAP_SET_COUNTS)) {
|
|
3731
|
+
if (getGlobalConfig().WarpDrive.debug.__INTERNAL_LOG_NATIVE_MAP_SET_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.__INTERNAL_LOG_NATIVE_MAP_SET_COUNTS) {
|
|
3732
|
+
// @ts-expect-error adding to globalThis
|
|
3733
|
+
globalThis.__primitiveInstanceId = 0;
|
|
3734
|
+
function interceptAndLog(klassName, methodName) {
|
|
3735
|
+
const klass = globalThis[klassName];
|
|
3736
|
+
if (methodName === 'constructor') {
|
|
3737
|
+
const instantiationLabel = `new ${klassName}()`;
|
|
3738
|
+
// @ts-expect-error
|
|
3739
|
+
globalThis[klassName] = class extends klass {
|
|
3740
|
+
// @ts-expect-error
|
|
3741
|
+
constructor(...args) {
|
|
3742
|
+
// eslint-disable-next-line
|
|
3743
|
+
super(...args);
|
|
3744
|
+
// @ts-expect-error
|
|
3745
|
+
|
|
3746
|
+
const instanceId = globalThis.__primitiveInstanceId++;
|
|
3747
|
+
// @ts-expect-error
|
|
3748
|
+
// eslint-disable-next-line
|
|
3749
|
+
globalThis.__WarpDriveMetricCountData[instantiationLabel] =
|
|
3750
|
+
// @ts-expect-error
|
|
3751
|
+
// eslint-disable-next-line
|
|
3752
|
+
(globalThis.__WarpDriveMetricCountData[instantiationLabel] || 0) + 1;
|
|
3753
|
+
// @ts-expect-error
|
|
3754
|
+
this.instanceName = `${klassName}:${instanceId} - ${new Error().stack?.split('\n')[2]}`;
|
|
3755
|
+
}
|
|
3756
|
+
};
|
|
3757
|
+
} else {
|
|
3758
|
+
// @ts-expect-error
|
|
3759
|
+
// eslint-disable-next-line
|
|
3760
|
+
const original = klass.prototype[methodName];
|
|
3761
|
+
const logName = `${klassName}.${methodName}`;
|
|
3762
|
+
|
|
3763
|
+
// @ts-expect-error
|
|
3764
|
+
klass.prototype[methodName] = function (...args) {
|
|
3765
|
+
// @ts-expect-error
|
|
3766
|
+
// eslint-disable-next-line
|
|
3767
|
+
globalThis.__WarpDriveMetricCountData[logName] = (globalThis.__WarpDriveMetricCountData[logName] || 0) + 1;
|
|
3768
|
+
// @ts-expect-error
|
|
3769
|
+
const {
|
|
3770
|
+
instanceName
|
|
3771
|
+
} = this;
|
|
3772
|
+
if (!instanceName) {
|
|
3773
|
+
// @ts-expect-error
|
|
3774
|
+
const instanceId = globalThis.__primitiveInstanceId++;
|
|
3775
|
+
// @ts-expect-error
|
|
3776
|
+
this.instanceName = `${klassName}.${methodName}:${instanceId} - ${new Error().stack?.split('\n')[2]}`;
|
|
3777
|
+
}
|
|
3778
|
+
const instanceLogName = `${logName} (${instanceName})`;
|
|
3779
|
+
// @ts-expect-error
|
|
3780
|
+
// eslint-disable-next-line
|
|
3781
|
+
globalThis.__WarpDriveMetricCountData[instanceLogName] =
|
|
3782
|
+
// @ts-expect-error
|
|
3783
|
+
// eslint-disable-next-line
|
|
3784
|
+
(globalThis.__WarpDriveMetricCountData[instanceLogName] || 0) + 1;
|
|
3785
|
+
// eslint-disable-next-line
|
|
3786
|
+
return original.apply(this, args);
|
|
3787
|
+
};
|
|
3788
|
+
}
|
|
3789
|
+
}
|
|
3790
|
+
interceptAndLog('Set', 'constructor');
|
|
3791
|
+
interceptAndLog('Set', 'add');
|
|
3792
|
+
interceptAndLog('Set', 'delete');
|
|
3793
|
+
interceptAndLog('Set', 'has');
|
|
3794
|
+
interceptAndLog('Set', 'set');
|
|
3795
|
+
interceptAndLog('Set', 'get');
|
|
3796
|
+
interceptAndLog('Map', 'constructor');
|
|
3797
|
+
interceptAndLog('Map', 'set');
|
|
3798
|
+
interceptAndLog('Map', 'delete');
|
|
3799
|
+
interceptAndLog('Map', 'has');
|
|
3800
|
+
interceptAndLog('Map', 'add');
|
|
3801
|
+
interceptAndLog('Map', 'get');
|
|
3802
|
+
interceptAndLog('WeakSet', 'constructor');
|
|
3803
|
+
interceptAndLog('WeakSet', 'add');
|
|
3804
|
+
interceptAndLog('WeakSet', 'delete');
|
|
3805
|
+
interceptAndLog('WeakSet', 'has');
|
|
3806
|
+
interceptAndLog('WeakSet', 'set');
|
|
3807
|
+
interceptAndLog('WeakSet', 'get');
|
|
3808
|
+
interceptAndLog('WeakMap', 'constructor');
|
|
3809
|
+
interceptAndLog('WeakMap', 'set');
|
|
3810
|
+
interceptAndLog('WeakMap', 'delete');
|
|
3811
|
+
interceptAndLog('WeakMap', 'has');
|
|
3812
|
+
interceptAndLog('WeakMap', 'add');
|
|
3813
|
+
interceptAndLog('WeakMap', 'get');
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
}
|
|
3817
|
+
}
|
|
3818
|
+
|
|
3498
3819
|
// `AwaitedKeys` is needed here to resolve any promise types like `PromiseBelongsTo`.
|
|
3499
3820
|
|
|
3500
3821
|
/**
|
|
@@ -3877,22 +4198,26 @@ class Store extends BaseClass {
|
|
|
3877
4198
|
opts.disableTestWaiter = typeof requestConfig.disableTestWaiter === 'boolean' ? requestConfig.disableTestWaiter : true;
|
|
3878
4199
|
}
|
|
3879
4200
|
}
|
|
3880
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
4201
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_REQUESTS)) {
|
|
4202
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_REQUESTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_REQUESTS) {
|
|
4203
|
+
let options;
|
|
4204
|
+
try {
|
|
4205
|
+
options = JSON.parse(JSON.stringify(requestConfig));
|
|
4206
|
+
} catch {
|
|
4207
|
+
options = requestConfig;
|
|
4208
|
+
}
|
|
4209
|
+
// eslint-disable-next-line no-console
|
|
4210
|
+
console.log(`request: [[START]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`, options);
|
|
3886
4211
|
}
|
|
3887
|
-
// eslint-disable-next-line no-console
|
|
3888
|
-
console.log(`request: [[START]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`, options);
|
|
3889
4212
|
}
|
|
3890
4213
|
const request = Object.assign({}, requestConfig, opts);
|
|
3891
4214
|
const future = this.requestManager.request(request);
|
|
3892
4215
|
future.onFinalize(() => {
|
|
3893
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
3894
|
-
|
|
3895
|
-
|
|
4216
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_REQUESTS)) {
|
|
4217
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_REQUESTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_REQUESTS) {
|
|
4218
|
+
// eslint-disable-next-line no-console
|
|
4219
|
+
console.log(`request: [[FINALIZE]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`);
|
|
4220
|
+
}
|
|
3896
4221
|
}
|
|
3897
4222
|
// skip flush for legacy belongsTo
|
|
3898
4223
|
if (requestConfig.op === 'findBelongsTo' && !requestConfig.url) {
|
|
@@ -4098,9 +4423,8 @@ class Store extends BaseClass {
|
|
|
4098
4423
|
This will cause the record to be destroyed and freed up for garbage collection.
|
|
4099
4424
|
Example
|
|
4100
4425
|
```javascript
|
|
4101
|
-
store.findRecord('post', '1')
|
|
4102
|
-
|
|
4103
|
-
});
|
|
4426
|
+
const { content: { data: post } } = await store.request(findRecord({ type: 'post', id: '1' }));
|
|
4427
|
+
store.unloadRecord(post);
|
|
4104
4428
|
```
|
|
4105
4429
|
@method unloadRecord
|
|
4106
4430
|
@public
|
|
@@ -5152,14 +5476,16 @@ class Store extends BaseClass {
|
|
|
5152
5476
|
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
5153
5477
|
assertDestroyingStore(this, '_push');
|
|
5154
5478
|
}
|
|
5155
|
-
if (macroCondition(getGlobalConfig().WarpDrive.
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5479
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_PAYLOADS)) {
|
|
5480
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_PAYLOADS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_PAYLOADS) {
|
|
5481
|
+
try {
|
|
5482
|
+
const data = JSON.parse(JSON.stringify(jsonApiDoc));
|
|
5483
|
+
// eslint-disable-next-line no-console
|
|
5484
|
+
console.log('EmberData | Payload - push', data);
|
|
5485
|
+
} catch {
|
|
5486
|
+
// eslint-disable-next-line no-console
|
|
5487
|
+
console.log('EmberData | Payload - push', jsonApiDoc);
|
|
5488
|
+
}
|
|
5163
5489
|
}
|
|
5164
5490
|
}
|
|
5165
5491
|
if (asyncFlush) {
|
|
@@ -5382,9 +5708,9 @@ function normalizeProperties(store, identifier, properties) {
|
|
|
5382
5708
|
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
5383
5709
|
assertRecordsPassedToHasMany(properties[prop]);
|
|
5384
5710
|
}
|
|
5385
|
-
properties[prop] = extractIdentifiersFromRecords(properties[prop]);
|
|
5711
|
+
properties[prop] = extractIdentifiersFromRecords$1(properties[prop]);
|
|
5386
5712
|
} else if (field.kind === 'belongsTo') {
|
|
5387
|
-
properties[prop] = extractIdentifierFromRecord(properties[prop]);
|
|
5713
|
+
properties[prop] = extractIdentifierFromRecord$1(properties[prop]);
|
|
5388
5714
|
}
|
|
5389
5715
|
}
|
|
5390
5716
|
}
|
|
@@ -5412,10 +5738,10 @@ function assertRecordsPassedToHasMany(records) {
|
|
|
5412
5738
|
});
|
|
5413
5739
|
}()) : {};
|
|
5414
5740
|
}
|
|
5415
|
-
function extractIdentifiersFromRecords(records) {
|
|
5416
|
-
return records.map(record => extractIdentifierFromRecord(record));
|
|
5741
|
+
function extractIdentifiersFromRecords$1(records) {
|
|
5742
|
+
return records.map(record => extractIdentifierFromRecord$1(record));
|
|
5417
5743
|
}
|
|
5418
|
-
function extractIdentifierFromRecord(recordOrPromiseRecord) {
|
|
5744
|
+
function extractIdentifierFromRecord$1(recordOrPromiseRecord) {
|
|
5419
5745
|
if (!recordOrPromiseRecord) {
|
|
5420
5746
|
return null;
|
|
5421
5747
|
}
|
|
@@ -6063,4 +6389,475 @@ function fetchContentAndHydrate(next, context, identifier, priority) {
|
|
|
6063
6389
|
}]
|
|
6064
6390
|
});
|
|
6065
6391
|
}
|
|
6066
|
-
|
|
6392
|
+
|
|
6393
|
+
/**
|
|
6394
|
+
@module @ember-data/store
|
|
6395
|
+
*/
|
|
6396
|
+
/**
|
|
6397
|
+
A `ManyArray` is a `MutableArray` that represents the contents of a has-many
|
|
6398
|
+
relationship.
|
|
6399
|
+
|
|
6400
|
+
The `ManyArray` is instantiated lazily the first time the relationship is
|
|
6401
|
+
requested.
|
|
6402
|
+
|
|
6403
|
+
This class is not intended to be directly instantiated by consuming applications.
|
|
6404
|
+
|
|
6405
|
+
### Inverses
|
|
6406
|
+
|
|
6407
|
+
Often, the relationships in Ember Data applications will have
|
|
6408
|
+
an inverse. For example, imagine the following models are
|
|
6409
|
+
defined:
|
|
6410
|
+
|
|
6411
|
+
```app/models/post.js
|
|
6412
|
+
import Model, { hasMany } from '@ember-data/model';
|
|
6413
|
+
|
|
6414
|
+
export default class PostModel extends Model {
|
|
6415
|
+
@hasMany('comment') comments;
|
|
6416
|
+
}
|
|
6417
|
+
```
|
|
6418
|
+
|
|
6419
|
+
```app/models/comment.js
|
|
6420
|
+
import Model, { belongsTo } from '@ember-data/model';
|
|
6421
|
+
|
|
6422
|
+
export default class CommentModel extends Model {
|
|
6423
|
+
@belongsTo('post') post;
|
|
6424
|
+
}
|
|
6425
|
+
```
|
|
6426
|
+
|
|
6427
|
+
If you created a new instance of `Post` and added
|
|
6428
|
+
a `Comment` record to its `comments` has-many
|
|
6429
|
+
relationship, you would expect the comment's `post`
|
|
6430
|
+
property to be set to the post that contained
|
|
6431
|
+
the has-many.
|
|
6432
|
+
|
|
6433
|
+
We call the record to which a relationship belongs-to the
|
|
6434
|
+
relationship's _owner_.
|
|
6435
|
+
|
|
6436
|
+
@class ManyArray
|
|
6437
|
+
@public
|
|
6438
|
+
*/
|
|
6439
|
+
class RelatedCollection extends IdentifierArray {
|
|
6440
|
+
/**
|
|
6441
|
+
The loading state of this array
|
|
6442
|
+
@property {Boolean} isLoaded
|
|
6443
|
+
@public
|
|
6444
|
+
*/
|
|
6445
|
+
|
|
6446
|
+
/**
|
|
6447
|
+
`true` if the relationship is polymorphic, `false` otherwise.
|
|
6448
|
+
@property {Boolean} isPolymorphic
|
|
6449
|
+
@private
|
|
6450
|
+
*/
|
|
6451
|
+
|
|
6452
|
+
/**
|
|
6453
|
+
Metadata associated with the request for async hasMany relationships.
|
|
6454
|
+
Example
|
|
6455
|
+
Given that the server returns the following JSON payload when fetching a
|
|
6456
|
+
hasMany relationship:
|
|
6457
|
+
```js
|
|
6458
|
+
{
|
|
6459
|
+
"comments": [{
|
|
6460
|
+
"id": 1,
|
|
6461
|
+
"comment": "This is the first comment",
|
|
6462
|
+
}, {
|
|
6463
|
+
// ...
|
|
6464
|
+
}],
|
|
6465
|
+
"meta": {
|
|
6466
|
+
"page": 1,
|
|
6467
|
+
"total": 5
|
|
6468
|
+
}
|
|
6469
|
+
}
|
|
6470
|
+
```
|
|
6471
|
+
You can then access the meta data via the `meta` property:
|
|
6472
|
+
```js
|
|
6473
|
+
let comments = await post.comments;
|
|
6474
|
+
let meta = comments.meta;
|
|
6475
|
+
// meta.page => 1
|
|
6476
|
+
// meta.total => 5
|
|
6477
|
+
```
|
|
6478
|
+
@property {Object | null} meta
|
|
6479
|
+
@public
|
|
6480
|
+
*/
|
|
6481
|
+
|
|
6482
|
+
/**
|
|
6483
|
+
* Retrieve the links for this relationship
|
|
6484
|
+
*
|
|
6485
|
+
@property {Object | null} links
|
|
6486
|
+
@public
|
|
6487
|
+
*/
|
|
6488
|
+
|
|
6489
|
+
constructor(options) {
|
|
6490
|
+
super(options);
|
|
6491
|
+
this.isLoaded = options.isLoaded || false;
|
|
6492
|
+
this.isAsync = options.isAsync || false;
|
|
6493
|
+
this.isPolymorphic = options.isPolymorphic || false;
|
|
6494
|
+
this.identifier = options.identifier;
|
|
6495
|
+
this.key = options.key;
|
|
6496
|
+
}
|
|
6497
|
+
[MUTATE](target, receiver, prop, args, _SIGNAL) {
|
|
6498
|
+
switch (prop) {
|
|
6499
|
+
case 'length 0':
|
|
6500
|
+
{
|
|
6501
|
+
Reflect.set(target, 'length', 0);
|
|
6502
|
+
mutateReplaceRelatedRecords(this, [], _SIGNAL);
|
|
6503
|
+
return true;
|
|
6504
|
+
}
|
|
6505
|
+
case 'replace cell':
|
|
6506
|
+
{
|
|
6507
|
+
const [index, prior, value] = args;
|
|
6508
|
+
target[index] = value;
|
|
6509
|
+
mutateReplaceRelatedRecord(this, {
|
|
6510
|
+
value,
|
|
6511
|
+
prior,
|
|
6512
|
+
index
|
|
6513
|
+
}, _SIGNAL);
|
|
6514
|
+
return true;
|
|
6515
|
+
}
|
|
6516
|
+
case 'push':
|
|
6517
|
+
{
|
|
6518
|
+
const newValues = extractIdentifiersFromRecords(args);
|
|
6519
|
+
assertNoDuplicates(this, target, currentState => currentState.push(...newValues), `Cannot push duplicates to a hasMany's state.`);
|
|
6520
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
6521
|
+
// dedupe
|
|
6522
|
+
const seen = new Set(target);
|
|
6523
|
+
const unique = new Set();
|
|
6524
|
+
args.forEach(item => {
|
|
6525
|
+
const identifier = recordIdentifierFor(item);
|
|
6526
|
+
if (!seen.has(identifier)) {
|
|
6527
|
+
seen.add(identifier);
|
|
6528
|
+
unique.add(item);
|
|
6529
|
+
}
|
|
6530
|
+
});
|
|
6531
|
+
const newArgs = Array.from(unique);
|
|
6532
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
6533
|
+
if (newArgs.length) {
|
|
6534
|
+
mutateAddToRelatedRecords(this, {
|
|
6535
|
+
value: extractIdentifiersFromRecords(newArgs)
|
|
6536
|
+
}, _SIGNAL);
|
|
6537
|
+
}
|
|
6538
|
+
return result;
|
|
6539
|
+
}
|
|
6540
|
+
|
|
6541
|
+
// else, no dedupe, error on duplicates
|
|
6542
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6543
|
+
if (newValues.length) {
|
|
6544
|
+
mutateAddToRelatedRecords(this, {
|
|
6545
|
+
value: newValues
|
|
6546
|
+
}, _SIGNAL);
|
|
6547
|
+
}
|
|
6548
|
+
return result;
|
|
6549
|
+
}
|
|
6550
|
+
case 'pop':
|
|
6551
|
+
{
|
|
6552
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6553
|
+
if (result) {
|
|
6554
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
6555
|
+
value: recordIdentifierFor(result)
|
|
6556
|
+
}, _SIGNAL);
|
|
6557
|
+
}
|
|
6558
|
+
return result;
|
|
6559
|
+
}
|
|
6560
|
+
case 'unshift':
|
|
6561
|
+
{
|
|
6562
|
+
const newValues = extractIdentifiersFromRecords(args);
|
|
6563
|
+
assertNoDuplicates(this, target, currentState => currentState.unshift(...newValues), `Cannot unshift duplicates to a hasMany's state.`);
|
|
6564
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
6565
|
+
// dedupe
|
|
6566
|
+
const seen = new Set(target);
|
|
6567
|
+
const unique = new Set();
|
|
6568
|
+
args.forEach(item => {
|
|
6569
|
+
const identifier = recordIdentifierFor(item);
|
|
6570
|
+
if (!seen.has(identifier)) {
|
|
6571
|
+
seen.add(identifier);
|
|
6572
|
+
unique.add(item);
|
|
6573
|
+
}
|
|
6574
|
+
});
|
|
6575
|
+
const newArgs = Array.from(unique);
|
|
6576
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
6577
|
+
if (newArgs.length) {
|
|
6578
|
+
mutateAddToRelatedRecords(this, {
|
|
6579
|
+
value: extractIdentifiersFromRecords(newArgs),
|
|
6580
|
+
index: 0
|
|
6581
|
+
}, _SIGNAL);
|
|
6582
|
+
}
|
|
6583
|
+
return result;
|
|
6584
|
+
}
|
|
6585
|
+
|
|
6586
|
+
// else, no dedupe, error on duplicates
|
|
6587
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6588
|
+
if (newValues.length) {
|
|
6589
|
+
mutateAddToRelatedRecords(this, {
|
|
6590
|
+
value: newValues,
|
|
6591
|
+
index: 0
|
|
6592
|
+
}, _SIGNAL);
|
|
6593
|
+
}
|
|
6594
|
+
return result;
|
|
6595
|
+
}
|
|
6596
|
+
case 'shift':
|
|
6597
|
+
{
|
|
6598
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6599
|
+
if (result) {
|
|
6600
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
6601
|
+
value: recordIdentifierFor(result),
|
|
6602
|
+
index: 0
|
|
6603
|
+
}, _SIGNAL);
|
|
6604
|
+
}
|
|
6605
|
+
return result;
|
|
6606
|
+
}
|
|
6607
|
+
case 'sort':
|
|
6608
|
+
{
|
|
6609
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6610
|
+
mutateSortRelatedRecords(this, result.map(recordIdentifierFor), _SIGNAL);
|
|
6611
|
+
return result;
|
|
6612
|
+
}
|
|
6613
|
+
case 'splice':
|
|
6614
|
+
{
|
|
6615
|
+
const [start, deleteCount, ...adds] = args;
|
|
6616
|
+
|
|
6617
|
+
// detect a full replace
|
|
6618
|
+
if (start === 0 && deleteCount === this[SOURCE].length) {
|
|
6619
|
+
const newValues = extractIdentifiersFromRecords(adds);
|
|
6620
|
+
assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot replace a hasMany's state with a new state that contains duplicates.`);
|
|
6621
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
6622
|
+
// dedupe
|
|
6623
|
+
const current = new Set(adds);
|
|
6624
|
+
const unique = Array.from(current);
|
|
6625
|
+
const newArgs = [start, deleteCount].concat(unique);
|
|
6626
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
6627
|
+
mutateReplaceRelatedRecords(this, extractIdentifiersFromRecords(unique), _SIGNAL);
|
|
6628
|
+
return result;
|
|
6629
|
+
}
|
|
6630
|
+
|
|
6631
|
+
// else, no dedupe, error on duplicates
|
|
6632
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6633
|
+
mutateReplaceRelatedRecords(this, newValues, _SIGNAL);
|
|
6634
|
+
return result;
|
|
6635
|
+
}
|
|
6636
|
+
const newValues = extractIdentifiersFromRecords(adds);
|
|
6637
|
+
assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot splice a hasMany's state with a new state that contains duplicates.`);
|
|
6638
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
6639
|
+
// dedupe
|
|
6640
|
+
const currentState = target.slice();
|
|
6641
|
+
currentState.splice(start, deleteCount);
|
|
6642
|
+
const seen = new Set(currentState);
|
|
6643
|
+
const unique = [];
|
|
6644
|
+
adds.forEach(item => {
|
|
6645
|
+
const identifier = recordIdentifierFor(item);
|
|
6646
|
+
if (!seen.has(identifier)) {
|
|
6647
|
+
seen.add(identifier);
|
|
6648
|
+
unique.push(item);
|
|
6649
|
+
}
|
|
6650
|
+
});
|
|
6651
|
+
const newArgs = [start, deleteCount, ...unique];
|
|
6652
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
6653
|
+
if (deleteCount > 0) {
|
|
6654
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
6655
|
+
value: result.map(recordIdentifierFor),
|
|
6656
|
+
index: start
|
|
6657
|
+
}, _SIGNAL);
|
|
6658
|
+
}
|
|
6659
|
+
if (unique.length > 0) {
|
|
6660
|
+
mutateAddToRelatedRecords(this, {
|
|
6661
|
+
value: extractIdentifiersFromRecords(unique),
|
|
6662
|
+
index: start
|
|
6663
|
+
}, _SIGNAL);
|
|
6664
|
+
}
|
|
6665
|
+
return result;
|
|
6666
|
+
}
|
|
6667
|
+
|
|
6668
|
+
// else, no dedupe, error on duplicates
|
|
6669
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6670
|
+
if (deleteCount > 0) {
|
|
6671
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
6672
|
+
value: result.map(recordIdentifierFor),
|
|
6673
|
+
index: start
|
|
6674
|
+
}, _SIGNAL);
|
|
6675
|
+
}
|
|
6676
|
+
if (newValues.length > 0) {
|
|
6677
|
+
mutateAddToRelatedRecords(this, {
|
|
6678
|
+
value: newValues,
|
|
6679
|
+
index: start
|
|
6680
|
+
}, _SIGNAL);
|
|
6681
|
+
}
|
|
6682
|
+
return result;
|
|
6683
|
+
}
|
|
6684
|
+
default:
|
|
6685
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
6686
|
+
{
|
|
6687
|
+
throw new Error(`unable to convert ${prop} into a transaction that updates the cache state for this record array`);
|
|
6688
|
+
}
|
|
6689
|
+
})() : {};
|
|
6690
|
+
}
|
|
6691
|
+
}
|
|
6692
|
+
notify() {
|
|
6693
|
+
const signal = this[ARRAY_SIGNAL];
|
|
6694
|
+
signal.shouldReset = true;
|
|
6695
|
+
notifyArray(this);
|
|
6696
|
+
}
|
|
6697
|
+
|
|
6698
|
+
/**
|
|
6699
|
+
Reloads all of the records in the manyArray. If the manyArray
|
|
6700
|
+
holds a relationship that was originally fetched using a links url
|
|
6701
|
+
EmberData will revisit the original links url to repopulate the
|
|
6702
|
+
relationship.
|
|
6703
|
+
If the ManyArray holds the result of a `store.query()` reload will
|
|
6704
|
+
re-run the original query.
|
|
6705
|
+
Example
|
|
6706
|
+
```javascript
|
|
6707
|
+
let user = store.peekRecord('user', '1')
|
|
6708
|
+
await login(user);
|
|
6709
|
+
let permissions = await user.permissions;
|
|
6710
|
+
await permissions.reload();
|
|
6711
|
+
```
|
|
6712
|
+
@method reload
|
|
6713
|
+
@public
|
|
6714
|
+
*/
|
|
6715
|
+
reload(options) {
|
|
6716
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
6717
|
+
if (!test) {
|
|
6718
|
+
throw new Error(`Expected the manager for ManyArray to implement reloadHasMany`);
|
|
6719
|
+
}
|
|
6720
|
+
})(typeof this._manager.reloadHasMany === 'function') : {};
|
|
6721
|
+
// TODO this is odd, we don't ask the store for anything else like this?
|
|
6722
|
+
return this._manager.reloadHasMany(this.key, options);
|
|
6723
|
+
}
|
|
6724
|
+
|
|
6725
|
+
/**
|
|
6726
|
+
Saves all of the records in the `ManyArray`.
|
|
6727
|
+
Note: this API can only be used in legacy mode with a configured Adapter.
|
|
6728
|
+
Example
|
|
6729
|
+
```javascript
|
|
6730
|
+
const { content: { data: inbox } } = await store.request(findRecord({ type: 'inbox', id: '1' }));
|
|
6731
|
+
let messages = await inbox.messages;
|
|
6732
|
+
messages.forEach((message) => {
|
|
6733
|
+
message.isRead = true;
|
|
6734
|
+
});
|
|
6735
|
+
messages.save();
|
|
6736
|
+
```
|
|
6737
|
+
@method save
|
|
6738
|
+
@public
|
|
6739
|
+
@return {PromiseArray} promise
|
|
6740
|
+
*/
|
|
6741
|
+
|
|
6742
|
+
/**
|
|
6743
|
+
Create a child record within the owner
|
|
6744
|
+
@method createRecord
|
|
6745
|
+
@public
|
|
6746
|
+
@param {Object} hash
|
|
6747
|
+
@return {Model} record
|
|
6748
|
+
*/
|
|
6749
|
+
createRecord(hash) {
|
|
6750
|
+
const {
|
|
6751
|
+
store
|
|
6752
|
+
} = this;
|
|
6753
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
6754
|
+
if (!test) {
|
|
6755
|
+
throw new Error(`Expected modelName to be set`);
|
|
6756
|
+
}
|
|
6757
|
+
})(this.modelName) : {};
|
|
6758
|
+
const record = store.createRecord(this.modelName, hash);
|
|
6759
|
+
this.push(record);
|
|
6760
|
+
return record;
|
|
6761
|
+
}
|
|
6762
|
+
destroy() {
|
|
6763
|
+
super.destroy(false);
|
|
6764
|
+
}
|
|
6765
|
+
}
|
|
6766
|
+
RelatedCollection.prototype.isAsync = false;
|
|
6767
|
+
RelatedCollection.prototype.isPolymorphic = false;
|
|
6768
|
+
RelatedCollection.prototype.identifier = null;
|
|
6769
|
+
RelatedCollection.prototype.cache = null;
|
|
6770
|
+
RelatedCollection.prototype._inverseIsAsync = false;
|
|
6771
|
+
RelatedCollection.prototype.key = '';
|
|
6772
|
+
RelatedCollection.prototype.DEPRECATED_CLASS_NAME = 'ManyArray';
|
|
6773
|
+
function assertRecordPassedToHasMany(record) {
|
|
6774
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
6775
|
+
if (!test) {
|
|
6776
|
+
throw new Error(`All elements of a hasMany relationship must be instances of Model, you passed ${typeof record}`);
|
|
6777
|
+
}
|
|
6778
|
+
})(function () {
|
|
6779
|
+
try {
|
|
6780
|
+
recordIdentifierFor(record);
|
|
6781
|
+
return true;
|
|
6782
|
+
} catch {
|
|
6783
|
+
return false;
|
|
6784
|
+
}
|
|
6785
|
+
}()) : {};
|
|
6786
|
+
}
|
|
6787
|
+
function extractIdentifiersFromRecords(records) {
|
|
6788
|
+
return records.map(extractIdentifierFromRecord);
|
|
6789
|
+
}
|
|
6790
|
+
function extractIdentifierFromRecord(recordOrPromiseRecord) {
|
|
6791
|
+
assertRecordPassedToHasMany(recordOrPromiseRecord);
|
|
6792
|
+
return recordIdentifierFor(recordOrPromiseRecord);
|
|
6793
|
+
}
|
|
6794
|
+
function assertNoDuplicates(collection, target, callback, reason) {
|
|
6795
|
+
const state = target.slice();
|
|
6796
|
+
callback(state);
|
|
6797
|
+
if (state.length !== new Set(state).size) {
|
|
6798
|
+
const duplicates = state.filter((currentValue, currentIndex) => state.indexOf(currentValue) !== currentIndex);
|
|
6799
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
6800
|
+
deprecate(`${reason} This behavior is deprecated. Found duplicates for the following records within the new state provided to \`<${collection.identifier.type}:${collection.identifier.id || collection.identifier.lid}>.${collection.key}\`\n\t- ${Array.from(new Set(duplicates)).map(r => isStableIdentifier(r) ? r.lid : recordIdentifierFor(r).lid).sort((a, b) => a.localeCompare(b)).join('\n\t- ')}`, false, {
|
|
6801
|
+
id: 'ember-data:deprecate-many-array-duplicates',
|
|
6802
|
+
for: 'ember-data',
|
|
6803
|
+
until: '6.0',
|
|
6804
|
+
since: {
|
|
6805
|
+
enabled: '5.3',
|
|
6806
|
+
available: '4.13'
|
|
6807
|
+
}
|
|
6808
|
+
});
|
|
6809
|
+
} else {
|
|
6810
|
+
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- ')}`);
|
|
6811
|
+
}
|
|
6812
|
+
}
|
|
6813
|
+
}
|
|
6814
|
+
function mutateAddToRelatedRecords(collection, operationInfo, _SIGNAL) {
|
|
6815
|
+
mutate(collection, {
|
|
6816
|
+
op: 'addToRelatedRecords',
|
|
6817
|
+
record: collection.identifier,
|
|
6818
|
+
field: collection.key,
|
|
6819
|
+
...operationInfo
|
|
6820
|
+
}, _SIGNAL);
|
|
6821
|
+
}
|
|
6822
|
+
function mutateRemoveFromRelatedRecords(collection, operationInfo, _SIGNAL) {
|
|
6823
|
+
mutate(collection, {
|
|
6824
|
+
op: 'removeFromRelatedRecords',
|
|
6825
|
+
record: collection.identifier,
|
|
6826
|
+
field: collection.key,
|
|
6827
|
+
...operationInfo
|
|
6828
|
+
}, _SIGNAL);
|
|
6829
|
+
}
|
|
6830
|
+
function mutateReplaceRelatedRecord(collection, operationInfo, _SIGNAL) {
|
|
6831
|
+
mutate(collection, {
|
|
6832
|
+
op: 'replaceRelatedRecord',
|
|
6833
|
+
record: collection.identifier,
|
|
6834
|
+
field: collection.key,
|
|
6835
|
+
...operationInfo
|
|
6836
|
+
}, _SIGNAL);
|
|
6837
|
+
}
|
|
6838
|
+
function mutateReplaceRelatedRecords(collection, value, _SIGNAL) {
|
|
6839
|
+
mutate(collection, {
|
|
6840
|
+
op: 'replaceRelatedRecords',
|
|
6841
|
+
record: collection.identifier,
|
|
6842
|
+
field: collection.key,
|
|
6843
|
+
value
|
|
6844
|
+
}, _SIGNAL);
|
|
6845
|
+
}
|
|
6846
|
+
function mutateSortRelatedRecords(collection, value, _SIGNAL) {
|
|
6847
|
+
mutate(collection, {
|
|
6848
|
+
op: 'sortRelatedRecords',
|
|
6849
|
+
record: collection.identifier,
|
|
6850
|
+
field: collection.key,
|
|
6851
|
+
value
|
|
6852
|
+
}, _SIGNAL);
|
|
6853
|
+
}
|
|
6854
|
+
function mutate(collection, mutation, _SIGNAL) {
|
|
6855
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
6856
|
+
if (!test) {
|
|
6857
|
+
throw new Error(`Expected the manager for ManyArray to implement mutate`);
|
|
6858
|
+
}
|
|
6859
|
+
})(typeof collection._manager.mutate === 'function') : {};
|
|
6860
|
+
collection._manager.mutate(mutation);
|
|
6861
|
+
addToTransaction(_SIGNAL);
|
|
6862
|
+
}
|
|
6863
|
+
export { ARRAY_SIGNAL as A, CacheHandler as C, IdentifierArray as I, MUTATE as M, RecordArrayManager as R, Store as S, _clearCaches as _, setIdentifierGenerationMethod as a, setIdentifierUpdateMethod as b, setIdentifierForgetMethod as c, setIdentifierResetMethod as d, setKeyInfoForResource as e, constructResource as f, coerceId as g, ensureStringId as h, isStableIdentifier as i, Collection as j, SOURCE as k, fastPush as l, removeRecordDataFor as m, notifyArray as n, setRecordIdentifier as o, peekCache as p, StoreMap as q, recordIdentifierFor as r, storeFor as s, setCacheFor as t, normalizeModelName as u, RelatedCollection as v, log as w, logGroup as x };
|