@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.
Files changed (47) hide show
  1. package/LICENSE.md +19 -7
  2. package/README.md +2 -2
  3. package/dist/-private.js +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/{handler-DX830Swd.js → many-array-D-iDvWAq.js} +954 -157
  6. package/dist/many-array-D-iDvWAq.js.map +1 -0
  7. package/logos/NCC-1701-a-blue.svg +4 -0
  8. package/logos/NCC-1701-a-gold.svg +4 -0
  9. package/logos/NCC-1701-a-gold_100.svg +1 -0
  10. package/logos/NCC-1701-a-gold_base-64.txt +1 -0
  11. package/logos/NCC-1701-a.svg +4 -0
  12. package/logos/README.md +4 -0
  13. package/logos/docs-badge.svg +2 -0
  14. package/logos/github-header.svg +444 -0
  15. package/logos/social1.png +0 -0
  16. package/logos/social2.png +0 -0
  17. package/logos/warp-drive-logo-dark.svg +4 -0
  18. package/logos/warp-drive-logo-gold.svg +4 -0
  19. package/package.json +24 -43
  20. package/unstable-preview-types/-private/caches/identifier-cache.d.ts.map +1 -1
  21. package/unstable-preview-types/-private/caches/instance-cache.d.ts.map +1 -1
  22. package/unstable-preview-types/-private/debug/utils.d.ts +9 -0
  23. package/unstable-preview-types/-private/debug/utils.d.ts.map +1 -0
  24. package/unstable-preview-types/-private/managers/cache-capabilities-manager.d.ts +3 -3
  25. package/unstable-preview-types/-private/managers/cache-capabilities-manager.d.ts.map +1 -1
  26. package/unstable-preview-types/-private/managers/cache-manager.d.ts +22 -0
  27. package/unstable-preview-types/-private/managers/cache-manager.d.ts.map +1 -1
  28. package/unstable-preview-types/-private/managers/notification-manager.d.ts +4 -4
  29. package/unstable-preview-types/-private/managers/notification-manager.d.ts.map +1 -1
  30. package/unstable-preview-types/-private/managers/record-array-manager.d.ts +2 -0
  31. package/unstable-preview-types/-private/managers/record-array-manager.d.ts.map +1 -1
  32. package/unstable-preview-types/-private/record-arrays/identifier-array.d.ts +11 -1
  33. package/unstable-preview-types/-private/record-arrays/identifier-array.d.ts.map +1 -1
  34. package/unstable-preview-types/-private/record-arrays/many-array.d.ts +199 -0
  35. package/unstable-preview-types/-private/record-arrays/many-array.d.ts.map +1 -0
  36. package/unstable-preview-types/-private/store-service.d.ts +61 -3
  37. package/unstable-preview-types/-private/store-service.d.ts.map +1 -1
  38. package/unstable-preview-types/-private.d.ts +2 -0
  39. package/unstable-preview-types/-private.d.ts.map +1 -1
  40. package/unstable-preview-types/-types/q/cache-capabilities-manager.d.ts +4 -4
  41. package/unstable-preview-types/-types/q/cache-capabilities-manager.d.ts.map +1 -1
  42. package/unstable-preview-types/-types/q/schema-service.d.ts +4 -4
  43. package/unstable-preview-types/-types/q/schema-service.d.ts.map +1 -1
  44. package/unstable-preview-types/index.d.ts +22 -20
  45. package/dist/handler-DX830Swd.js.map +0 -1
  46. /package/{ember-data-logo-dark.svg → logos/ember-data-logo-dark.svg} +0 -0
  47. /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, setTransient, peekTransient } from '@warp-drive/core-types/-private';
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 || IDENTIFIERS.has(identifier);
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.debug.LOG_IDENTIFIERS)) {
314
- // eslint-disable-next-line no-console
315
- console.groupCollapsed(`Identifiers: ${shouldGenerate ? 'Generating' : 'Peeking'} Identifier`, resource);
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.debug.LOG_IDENTIFIERS)) {
326
- // eslint-disable-next-line no-console
327
- console.log(`Identifiers: cache HIT - Stable ${resource.lid}`);
328
- // eslint-disable-next-line no-console
329
- console.groupEnd();
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.debug.LOG_IDENTIFIERS)) {
337
- // eslint-disable-next-line no-console
338
- console.log(`Identifiers: ${lid ? 'no ' : ''}lid ${lid ? lid + ' ' : ''}determined for resource`, resource);
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.debug.LOG_IDENTIFIERS)) {
343
- // eslint-disable-next-line no-console
344
- console.groupEnd();
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.debug.LOG_IDENTIFIERS)) {
350
- // eslint-disable-next-line no-console
351
- console.groupEnd();
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.debug.LOG_IDENTIFIERS)) {
370
- // eslint-disable-next-line no-console
371
- console.groupEnd();
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.debug.LOG_IDENTIFIERS)) {
466
- // eslint-disable-next-line no-console
467
- console.log(`Identifiers: created identifier ${String(identifier)} for newly generated resource`, data);
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.debug.LOG_IDENTIFIERS)) {
515
- // eslint-disable-next-line no-console
516
- console.log(`Identifiers: merged identifiers ${generatedIdentifier.lid} and ${existingIdentifier.lid} for resource into ${identifier.lid}`, data);
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.debug.LOG_IDENTIFIERS)) {
527
- // eslint-disable-next-line no-console
528
- console.log(`Identifiers: updated id for identifier ${identifier.lid} from '${String(id)}' to '${String(newId)}' for resource`, data);
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.debug.LOG_IDENTIFIERS)) {
541
- // eslint-disable-next-line no-console
542
- console.log(`Identifiers: updated identifier ${identifier.lid} resource`, data);
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.debug.LOG_IDENTIFIERS)) {
627
- // eslint-disable-next-line no-console
628
- console.log(`Identifiers: released identifier ${identifierObject.lid}`);
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
- get lid() {
646
- return recordIdentifier.lid;
647
- },
665
+ type: recordIdentifier.type,
666
+ lid: recordIdentifier.lid,
648
667
  get id() {
649
668
  return recordIdentifier.id;
650
- },
651
- get type() {
652
- return recordIdentifier.type;
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(wrapper, 'toString', {
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(wrapper, 'toJSON', {
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[DEBUG_CLIENT_ORIGINATED] = clientOriginated;
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.debug.LOG_IDENTIFIERS)) {
779
- // eslint-disable-next-line no-console
780
- console.log(`Identifiers: cache ${identifier ? 'HIT' : 'MISS'} - Non-Stable ${lid}`, resource);
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.debug.LOG_INSTANCE_CACHE)) {
1256
- // eslint-disable-next-line no-console
1257
- console.log(`InstanceCache: created Record for ${String(identifier)}`, properties);
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.debug.LOG_INSTANCE_CACHE)) {
1304
- // eslint-disable-next-line no-console
1305
- console.log(`InstanceCache: disconnected ${String(identifier)}`);
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.debug.LOG_INSTANCE_CACHE)) {
1322
- // eslint-disable-next-line no-console
1323
- console.groupCollapsed(`InstanceCache: unloading record for ${String(identifier)}`);
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.debug.LOG_INSTANCE_CACHE)) {
1337
- // eslint-disable-next-line no-console
1338
- console.log(`InstanceCache: destroyed record for ${String(identifier)}`);
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.debug.LOG_INSTANCE_CACHE)) {
1345
- // eslint-disable-next-line no-console
1346
- console.log(`InstanceCache: destroyed cache for ${String(identifier)}`);
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.debug.LOG_INSTANCE_CACHE)) {
1353
- // eslint-disable-next-line no-console
1354
- console.log(`InstanceCache: unloaded RecordData for ${String(identifier)}`);
1355
- // eslint-disable-next-line no-console
1356
- console.groupEnd();
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.debug.LOG_INSTANCE_CACHE)) {
1412
- // eslint-disable-next-line no-console
1413
- console.log(`InstanceCache: updating id to '${id}' for record ${String(identifier)}`);
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 CacheOperations.has(value);
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 _unsubscribe(tokens, token, cache) {
2171
- const identifier = tokens.get(token);
2172
- if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS)) {
2173
- if (!identifier) {
2174
- // eslint-disable-next-line no-console
2175
- console.log('Passed unknown unsubscribe token to unsubscribe', identifier);
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
- tokens.delete(token);
2180
- const map = cache.get(identifier);
2181
- map?.delete(token);
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 map = this._cache.get(identifier);
2240
- if (!map) {
2241
- map = new Map();
2242
- this._cache.set(identifier, map);
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
- const unsubToken = macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? {
2245
- _tokenRef: tokenId++
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(this._tokens, token, this._cache);
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.debug.LOG_NOTIFICATIONS)) {
2284
- // eslint-disable-next-line no-console
2285
- console.log(`Notifying: Expected to receive a stable Identifier to notify '${value}' '${key || ''}' with, but ${String(identifier)} is not in the cache`, identifier);
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
- if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS)) {
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
- this._scheduleNotify();
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.debug.LOG_NOTIFICATIONS)) {
2338
- // eslint-disable-next-line no-console
2339
- console.log(`Notifying: ${String(identifier)}\t${value}\t${key || ''}`);
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 callbackMap = this._cache.get(identifier);
2352
- if (!callbackMap || !callbackMap.size) {
2549
+ const callbacks = this._cache.get(identifier);
2550
+ if (!callbacks || !callbacks.length) {
2353
2551
  return false;
2354
2552
  }
2355
- callbackMap.forEach(cb => {
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$1(value);
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 IdentifierArray.prototype;
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$1(record) {
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.debug.LOG_REQUESTS)) {
3881
- let options;
3882
- try {
3883
- options = JSON.parse(JSON.stringify(requestConfig));
3884
- } catch {
3885
- options = requestConfig;
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.debug.LOG_REQUESTS)) {
3894
- // eslint-disable-next-line no-console
3895
- console.log(`request: [[FINALIZE]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`);
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').then(function(post) {
4102
- store.unloadRecord(post);
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.debug.LOG_PAYLOADS)) {
5156
- try {
5157
- const data = JSON.parse(JSON.stringify(jsonApiDoc));
5158
- // eslint-disable-next-line no-console
5159
- console.log('EmberData | Payload - push', data);
5160
- } catch {
5161
- // eslint-disable-next-line no-console
5162
- console.log('EmberData | Payload - push', jsonApiDoc);
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
- 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 };
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 };