@ember-data/store 5.4.0-beta.14 → 5.4.0-beta.16

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 (50) hide show
  1. package/LICENSE.md +19 -7
  2. package/README.md +5 -8
  3. package/dist/-private.js +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/{handler-CW2kp6Ua.js → many-array-V2cR1muR.js} +935 -153
  6. package/dist/many-array-V2cR1muR.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/cache-handler/handler.d.ts +0 -2
  21. package/unstable-preview-types/-private/cache-handler/handler.d.ts.map +1 -1
  22. package/unstable-preview-types/-private/caches/identifier-cache.d.ts.map +1 -1
  23. package/unstable-preview-types/-private/caches/instance-cache.d.ts.map +1 -1
  24. package/unstable-preview-types/-private/debug/utils.d.ts +9 -0
  25. package/unstable-preview-types/-private/debug/utils.d.ts.map +1 -0
  26. package/unstable-preview-types/-private/managers/cache-capabilities-manager.d.ts +3 -3
  27. package/unstable-preview-types/-private/managers/cache-capabilities-manager.d.ts.map +1 -1
  28. package/unstable-preview-types/-private/managers/cache-manager.d.ts +22 -0
  29. package/unstable-preview-types/-private/managers/cache-manager.d.ts.map +1 -1
  30. package/unstable-preview-types/-private/managers/notification-manager.d.ts +4 -4
  31. package/unstable-preview-types/-private/managers/notification-manager.d.ts.map +1 -1
  32. package/unstable-preview-types/-private/managers/record-array-manager.d.ts +2 -0
  33. package/unstable-preview-types/-private/managers/record-array-manager.d.ts.map +1 -1
  34. package/unstable-preview-types/-private/record-arrays/identifier-array.d.ts +11 -1
  35. package/unstable-preview-types/-private/record-arrays/identifier-array.d.ts.map +1 -1
  36. package/unstable-preview-types/-private/record-arrays/many-array.d.ts +199 -0
  37. package/unstable-preview-types/-private/record-arrays/many-array.d.ts.map +1 -0
  38. package/unstable-preview-types/-private/store-service.d.ts +64 -9
  39. package/unstable-preview-types/-private/store-service.d.ts.map +1 -1
  40. package/unstable-preview-types/-private.d.ts +2 -0
  41. package/unstable-preview-types/-private.d.ts.map +1 -1
  42. package/unstable-preview-types/-types/q/cache-capabilities-manager.d.ts +4 -4
  43. package/unstable-preview-types/-types/q/cache-capabilities-manager.d.ts.map +1 -1
  44. package/unstable-preview-types/-types/q/schema-service.d.ts +4 -4
  45. package/unstable-preview-types/-types/q/schema-service.d.ts.map +1 -1
  46. package/unstable-preview-types/index.d.ts +24 -25
  47. package/unstable-preview-types/index.d.ts.map +1 -1
  48. package/dist/handler-CW2kp6Ua.js.map +0 -1
  49. /package/{ember-data-logo-dark.svg → logos/ember-data-logo-dark.svg} +0 -0
  50. /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 { SkipCache, EnableHydration } from '@warp-drive/core-types/request';
4
- import { getOrSetGlobal, setTransient, peekTransient } from '@warp-drive/core-types/-private';
3
+ import { setLogging, getRuntimeConfig } from '@warp-drive/build-config/runtime';
4
+ import { EnableHydration, SkipCache } from '@warp-drive/core-types/request';
5
+ import { getOrSetGlobal, peekTransient, setTransient } from '@warp-drive/core-types/-private';
6
+ import { _backburner } from '@ember/runloop';
7
+ import { defineSignal, createSignal, subscribe, createArrayTags, addToTransaction, addTransactionCB } from '@ember-data/tracking/-private';
5
8
  import { CACHE_OWNER, DEBUG_STALE_CACHE_OWNER, DEBUG_CLIENT_ORIGINATED, DEBUG_IDENTIFIER_BUCKET } from '@warp-drive/core-types/identifier';
6
9
  import { dasherize } from '@ember-data/request-utils/string';
7
- import { defineSignal, createSignal, subscribe, createArrayTags, addToTransaction, addTransactionCB } from '@ember-data/tracking/-private';
8
- import { _backburner } from '@ember/runloop';
9
10
  import { compat } from '@ember-data/tracking';
10
11
 
11
12
  /**
@@ -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,7 +658,6 @@ 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
@@ -692,7 +712,6 @@ function makeStableRecordIdentifier(recordIdentifier, bucket, clientOriginated)
692
712
  });
693
713
  wrapper[DEBUG_CLIENT_ORIGINATED] = clientOriginated;
694
714
  wrapper[DEBUG_IDENTIFIER_BUCKET] = bucket;
695
- IDENTIFIERS.add(wrapper);
696
715
  DEBUG_MAP.set(wrapper, recordIdentifier);
697
716
  wrapper = freeze(wrapper);
698
717
  return wrapper;
@@ -775,9 +794,11 @@ function detectMerge(cache, keyInfo, identifier, data) {
775
794
  }
776
795
  function getIdentifierFromLid(cache, lid, resource) {
777
796
  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);
797
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_IDENTIFIERS)) {
798
+ if (getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_IDENTIFIERS) {
799
+ // eslint-disable-next-line no-console
800
+ console.log(`Identifiers: cache ${identifier ? 'HIT' : 'MISS'} - Non-Stable ${lid}`, resource);
801
+ }
781
802
  }
782
803
  return identifier || null;
783
804
  }
@@ -796,6 +817,87 @@ function addResourceToCache(cache, identifier) {
796
817
  typeSet.id.set(identifier.id, identifier);
797
818
  }
798
819
  }
820
+ const TEXT_COLORS = {
821
+ TEXT: 'inherit',
822
+ notify: ['white', 'white', 'inherit', 'magenta', 'inherit'],
823
+ 'reactive-ui': ['white', 'white', 'inherit', 'magenta', 'inherit'],
824
+ graph: ['white', 'white', 'inherit', 'magenta', 'inherit'],
825
+ request: ['white', 'white', 'inherit', 'magenta', 'inherit'],
826
+ cache: ['white', 'white', 'inherit', 'magenta', 'inherit']
827
+ };
828
+ const BG_COLORS = {
829
+ TEXT: 'transparent',
830
+ notify: ['dimgray', 'cadetblue', 'transparent', 'transparent', 'transparent'],
831
+ 'reactive-ui': ['dimgray', 'cadetblue', 'transparent', 'transparent', 'transparent'],
832
+ graph: ['dimgray', 'cadetblue', 'transparent', 'transparent', 'transparent'],
833
+ request: ['dimgray', 'cadetblue', 'transparent', 'transparent', 'transparent'],
834
+ cache: ['dimgray', 'cadetblue', 'transparent', 'transparent', 'transparent']
835
+ };
836
+ const NOTIFY_BORDER = {
837
+ TEXT: 0,
838
+ notify: [3, 2, 0, 0, 0],
839
+ 'reactive-ui': [3, 2, 0, 0, 0],
840
+ graph: [3, 2, 0, 0, 0],
841
+ request: [3, 2, 0, 0, 0],
842
+ cache: [3, 2, 0, 0, 0]
843
+ };
844
+ const LIGHT_DARK_ALT = {
845
+ lightgreen: 'green',
846
+ green: 'lightgreen'
847
+ };
848
+ function badge(isLight, color, bgColor, border) {
849
+ 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};`];
850
+ }
851
+ function colorForBucket(isLight, scope, bucket) {
852
+ if (scope === 'notify') {
853
+ 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]);
854
+ }
855
+ if (scope === 'reactive-ui') {
856
+ 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]);
857
+ }
858
+ if (scope === 'cache') {
859
+ 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]);
860
+ }
861
+ return badge(isLight, TEXT_COLORS[scope][3], BG_COLORS[scope][3], NOTIFY_BORDER[scope][3]);
862
+ }
863
+ function logGroup(scope, prefix, subScop1, subScop2, subScop3, subScop4) {
864
+ // eslint-disable-next-line no-console
865
+ console.groupCollapsed(..._log(scope, prefix, subScop1, subScop2, subScop3, subScop4));
866
+ }
867
+ function log(scope, prefix, subScop1, subScop2, subScop3, subScop4) {
868
+ // eslint-disable-next-line no-console
869
+ console.log(..._log(scope, prefix, subScop1, subScop2, subScop3, subScop4));
870
+ }
871
+ function correctColor(isLight, color) {
872
+ if (!isLight) {
873
+ return color;
874
+ }
875
+ return color in LIGHT_DARK_ALT ? LIGHT_DARK_ALT[color] : color;
876
+ }
877
+ function isLightMode() {
878
+ if (window?.matchMedia?.('(prefers-color-scheme: light)').matches) {
879
+ return true;
880
+ }
881
+ return false;
882
+ }
883
+ function _log(scope, prefix, subScop1, subScop2, subScop3, subScop4) {
884
+ const isLight = isLightMode();
885
+ switch (scope) {
886
+ case 'reactive-ui':
887
+ case 'notify':
888
+ {
889
+ const scopePath = prefix ? `[${prefix}] ${scope}` : scope;
890
+ const path = subScop4 ? `${subScop3}.${subScop4}` : subScop3;
891
+ 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)];
892
+ }
893
+ case 'cache':
894
+ {
895
+ const scopePath = prefix ? `${scope} (${prefix})` : scope;
896
+ 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])];
897
+ }
898
+ }
899
+ return [];
900
+ }
799
901
 
800
902
  /**
801
903
  @module @ember-data/store
@@ -1252,9 +1354,16 @@ class InstanceCache {
1252
1354
  setCacheFor(record, cache);
1253
1355
  StoreMap.set(record, this.store);
1254
1356
  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);
1357
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
1358
+ if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
1359
+ logGroup('reactive-ui', '', identifier.type, identifier.lid, 'created', '');
1360
+ // eslint-disable-next-line no-console
1361
+ console.log({
1362
+ properties
1363
+ });
1364
+ // eslint-disable-next-line no-console
1365
+ console.groupEnd();
1366
+ }
1258
1367
  }
1259
1368
  }
1260
1369
  return record;
@@ -1300,9 +1409,10 @@ class InstanceCache {
1300
1409
  this.store.identifierCache.forgetRecordIdentifier(identifier);
1301
1410
  removeRecordDataFor(identifier);
1302
1411
  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)}`);
1412
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
1413
+ if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
1414
+ log('reactive-ui', '', identifier.type, identifier.lid, 'disconnected', '');
1415
+ }
1306
1416
  }
1307
1417
  }
1308
1418
  unloadRecord(identifier) {
@@ -1318,9 +1428,11 @@ class InstanceCache {
1318
1428
  })() : {};
1319
1429
  }
1320
1430
  }
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)}`);
1431
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
1432
+ if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
1433
+ // eslint-disable-next-line no-console
1434
+ console.groupCollapsed(`InstanceCache: unloading record for ${String(identifier)}`);
1435
+ }
1324
1436
  }
1325
1437
 
1326
1438
  // TODO is this join still necessary?
@@ -1333,27 +1445,33 @@ class InstanceCache {
1333
1445
  StoreMap.delete(record);
1334
1446
  RecordCache.delete(record);
1335
1447
  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)}`);
1448
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
1449
+ if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
1450
+ // eslint-disable-next-line no-console
1451
+ console.log(`InstanceCache: destroyed record for ${String(identifier)}`);
1452
+ }
1339
1453
  }
1340
1454
  }
1341
1455
  if (cache) {
1342
1456
  cache.unloadRecord(identifier);
1343
1457
  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)}`);
1458
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
1459
+ if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
1460
+ // eslint-disable-next-line no-console
1461
+ console.log(`InstanceCache: destroyed cache for ${String(identifier)}`);
1462
+ }
1347
1463
  }
1348
1464
  } else {
1349
1465
  this.disconnect(identifier);
1350
1466
  }
1351
1467
  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();
1468
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
1469
+ if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
1470
+ // eslint-disable-next-line no-console
1471
+ console.log(`InstanceCache: unloaded RecordData for ${String(identifier)}`);
1472
+ // eslint-disable-next-line no-console
1473
+ console.groupEnd();
1474
+ }
1357
1475
  }
1358
1476
  });
1359
1477
  }
@@ -1408,9 +1526,11 @@ class InstanceCache {
1408
1526
  warn(`Your ${type} record was saved to the server, but the response does not have an id.`, !(oldId !== null && id === null));
1409
1527
  return;
1410
1528
  }
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)}`);
1529
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_INSTANCE_CACHE)) {
1530
+ if (getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE || globalThis.getWarpDriveRuntimeConfig().debug.LOG_INSTANCE_CACHE) {
1531
+ // eslint-disable-next-line no-console
1532
+ console.log(`InstanceCache: updating id to '${id}' for record ${String(identifier)}`);
1533
+ }
1414
1534
  }
1415
1535
  const existingIdentifier = this.store.identifierCache.peekRecordIdentifier({
1416
1536
  type,
@@ -1727,7 +1847,9 @@ class CacheManager {
1727
1847
  peek(identifier) {
1728
1848
  return this.#cache.peek(identifier);
1729
1849
  }
1730
-
1850
+ peekRemoteState(identifier) {
1851
+ return this.#cache.peekRemoteState(identifier);
1852
+ }
1731
1853
  /**
1732
1854
  * Peek the Cache for the existing request data associated with
1733
1855
  * a cacheable request
@@ -1950,6 +2072,19 @@ class CacheManager {
1950
2072
  return this.#cache.getAttr(identifier, propertyName);
1951
2073
  }
1952
2074
 
2075
+ /**
2076
+ * Retrieve the remote state for an attribute from the cache
2077
+ *
2078
+ * @method getRemoteAttr
2079
+ * @public
2080
+ * @param identifier
2081
+ * @param propertyName
2082
+ * @return {unknown}
2083
+ */
2084
+ getRemoteAttr(identifier, propertyName) {
2085
+ return this.#cache.getRemoteAttr(identifier, propertyName);
2086
+ }
2087
+
1953
2088
  /**
1954
2089
  * Mutate the data for an attribute in the cache
1955
2090
  *
@@ -2074,6 +2209,19 @@ class CacheManager {
2074
2209
  return this.#cache.getRelationship(identifier, propertyName);
2075
2210
  }
2076
2211
 
2212
+ /**
2213
+ * Query the cache for the remote state of a relationship property
2214
+ *
2215
+ * @method getRelationship
2216
+ * @public
2217
+ * @param identifier
2218
+ * @param propertyName
2219
+ * @return resource relationship object
2220
+ */
2221
+ getRemoteRelationship(identifier, propertyName) {
2222
+ return this.#cache.getRemoteRelationship(identifier, propertyName);
2223
+ }
2224
+
2077
2225
  // Resource State
2078
2226
  // ===============
2079
2227
 
@@ -2158,27 +2306,51 @@ class CacheManager {
2158
2306
  * @module @ember-data/store
2159
2307
  */
2160
2308
 
2161
- let tokenId = 0;
2162
- const CacheOperations = new Set(['added', 'removed', 'state', 'updated', 'invalidated']);
2163
2309
  function isCacheOperationValue(value) {
2164
- return CacheOperations.has(value);
2310
+ return value === 'added' || value === 'state' || value === 'updated' || value === 'removed' || value === 'invalidated';
2165
2311
  }
2166
2312
  function runLoopIsFlushing() {
2167
2313
  //@ts-expect-error
2168
2314
  return !!_backburner.currentInstance && _backburner._autorun !== true;
2169
2315
  }
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);
2316
+ function count(label) {
2317
+ // @ts-expect-error
2318
+ // eslint-disable-next-line
2319
+ globalThis.__WarpDriveMetricCountData[label] = (globalThis.__WarpDriveMetricCountData[label] || 0) + 1;
2320
+ }
2321
+ function asInternalToken(token) {
2322
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2323
+ if (!test) {
2324
+ throw new Error(`Expected a token with a 'for' property`);
2325
+ }
2326
+ })(token && typeof token === 'function' && 'for' in token) : {};
2327
+ }
2328
+ function _unsubscribe(token, cache) {
2329
+ asInternalToken(token);
2330
+ const identifier = token.for;
2331
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
2332
+ if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
2333
+ if (!identifier) {
2334
+ // eslint-disable-next-line no-console
2335
+ console.log('Passed unknown unsubscribe token to unsubscribe', identifier);
2336
+ }
2176
2337
  }
2177
2338
  }
2178
2339
  if (identifier) {
2179
- tokens.delete(token);
2180
- const map = cache.get(identifier);
2181
- map?.delete(token);
2340
+ const callbacks = cache.get(identifier);
2341
+ if (!callbacks) {
2342
+ return;
2343
+ }
2344
+ const index = callbacks.indexOf(token);
2345
+ if (index === -1) {
2346
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2347
+ if (!test) {
2348
+ throw new Error(`Cannot unsubscribe a token that is not subscribed`);
2349
+ }
2350
+ })(index !== -1) : {};
2351
+ return;
2352
+ }
2353
+ callbacks.splice(index, 1);
2182
2354
  }
2183
2355
  }
2184
2356
 
@@ -2199,7 +2371,6 @@ class NotificationManager {
2199
2371
  this._buffered = new Map();
2200
2372
  this._hasFlush = false;
2201
2373
  this._cache = new Map();
2202
- this._tokens = new Map();
2203
2374
  }
2204
2375
 
2205
2376
  /**
@@ -2236,17 +2407,26 @@ class NotificationManager {
2236
2407
  throw new Error(`Expected to receive a stable Identifier to subscribe to`);
2237
2408
  }
2238
2409
  })(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);
2410
+ let callbacks = this._cache.get(identifier);
2411
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2412
+ if (!test) {
2413
+ throw new Error(`expected to receive a valid callback`);
2414
+ }
2415
+ })(typeof callback === 'function') : {};
2416
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2417
+ if (!test) {
2418
+ throw new Error(`cannot subscribe with the same callback twice`);
2419
+ }
2420
+ })(!callbacks || !callbacks.includes(callback)) : {};
2421
+ // we use the callback as the cancellation token
2422
+ //@ts-expect-error
2423
+ callback.for = identifier;
2424
+ if (!callbacks) {
2425
+ callbacks = [];
2426
+ this._cache.set(identifier, callbacks);
2243
2427
  }
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;
2428
+ callbacks.push(callback);
2429
+ return callback;
2250
2430
  }
2251
2431
 
2252
2432
  /**
@@ -2258,7 +2438,7 @@ class NotificationManager {
2258
2438
  */
2259
2439
  unsubscribe(token) {
2260
2440
  if (!this.isDestroyed) {
2261
- _unsubscribe(this._tokens, token, this._cache);
2441
+ _unsubscribe(token, this._cache);
2262
2442
  }
2263
2443
  }
2264
2444
 
@@ -2280,17 +2460,15 @@ class NotificationManager {
2280
2460
  }
2281
2461
  })(!key || value === 'attributes' || value === 'relationships') : {};
2282
2462
  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);
2463
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
2464
+ if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
2465
+ // eslint-disable-next-line no-console
2466
+ console.log(`Notifying: Expected to receive a stable Identifier to notify '${value}' '${key || ''}' with, but ${String(identifier)} is not in the cache`, identifier);
2467
+ }
2286
2468
  }
2287
2469
  return false;
2288
2470
  }
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);
2471
+ const hasSubscribers = Boolean(this._cache.get(identifier)?.length);
2294
2472
  if (isCacheOperationValue(value) || hasSubscribers) {
2295
2473
  let buffer = this._buffered.get(identifier);
2296
2474
  if (!buffer) {
@@ -2298,7 +2476,22 @@ class NotificationManager {
2298
2476
  this._buffered.set(identifier, buffer);
2299
2477
  }
2300
2478
  buffer.push([value, key]);
2301
- this._scheduleNotify();
2479
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
2480
+ if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
2481
+ count(`notify ${'type' in identifier ? identifier.type : '<document>'} ${value} ${key}`);
2482
+ }
2483
+ }
2484
+ if (!this._scheduleNotify()) {
2485
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
2486
+ if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
2487
+ log('notify', 'buffered', `${'type' in identifier ? identifier.type : 'document'}`, identifier.lid, `${value}`, key || '');
2488
+ }
2489
+ }
2490
+ }
2491
+ } else if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
2492
+ if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
2493
+ count(`DISCARDED notify ${'type' in identifier ? identifier.type : '<document>'} ${value} ${key}`);
2494
+ }
2302
2495
  }
2303
2496
  return hasSubscribers;
2304
2497
  }
@@ -2309,14 +2502,15 @@ class NotificationManager {
2309
2502
  const asyncFlush = this.store._enableAsyncFlush;
2310
2503
  if (this._hasFlush) {
2311
2504
  if (asyncFlush !== false && !runLoopIsFlushing()) {
2312
- return;
2505
+ return false;
2313
2506
  }
2314
2507
  }
2315
2508
  if (asyncFlush && !runLoopIsFlushing()) {
2316
2509
  this._hasFlush = true;
2317
- return;
2510
+ return false;
2318
2511
  }
2319
2512
  this._flush();
2513
+ return true;
2320
2514
  }
2321
2515
  _flush() {
2322
2516
  const buffered = this._buffered;
@@ -2334,9 +2528,10 @@ class NotificationManager {
2334
2528
  this._onFlushCB = undefined;
2335
2529
  }
2336
2530
  _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 || ''}`);
2531
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
2532
+ if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
2533
+ log('notify', '', `${'type' in identifier ? identifier.type : 'document'}`, identifier.lid, `${value}`, key || '');
2534
+ }
2340
2535
  }
2341
2536
 
2342
2537
  // TODO for documents this will need to switch based on Identifier kind
@@ -2348,11 +2543,11 @@ class NotificationManager {
2348
2543
  });
2349
2544
  }
2350
2545
  }
2351
- const callbackMap = this._cache.get(identifier);
2352
- if (!callbackMap || !callbackMap.size) {
2546
+ const callbacks = this._cache.get(identifier);
2547
+ if (!callbacks || !callbacks.length) {
2353
2548
  return false;
2354
2549
  }
2355
- callbackMap.forEach(cb => {
2550
+ callbacks.forEach(cb => {
2356
2551
  // @ts-expect-error overload doesn't narrow within body
2357
2552
  cb(identifier, value, key);
2358
2553
  });
@@ -2360,7 +2555,6 @@ class NotificationManager {
2360
2555
  }
2361
2556
  destroy() {
2362
2557
  this.isDestroyed = true;
2363
- this._tokens.clear();
2364
2558
  this._cache.clear();
2365
2559
  }
2366
2560
  }
@@ -2682,7 +2876,7 @@ class IdentifierArray {
2682
2876
  return false;
2683
2877
  }
2684
2878
  const original = target[index];
2685
- const newIdentifier = extractIdentifierFromRecord$1(value);
2879
+ const newIdentifier = extractIdentifierFromRecord$2(value);
2686
2880
  macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2687
2881
  if (!test) {
2688
2882
  throw new Error(`Expected a record`);
@@ -2723,7 +2917,7 @@ class IdentifierArray {
2723
2917
  return Reflect.deleteProperty(target, prop);
2724
2918
  },
2725
2919
  getPrototypeOf() {
2726
- return IdentifierArray.prototype;
2920
+ return Array.prototype;
2727
2921
  }
2728
2922
  });
2729
2923
  createArrayTags(proxy, _SIGNAL);
@@ -2866,7 +3060,7 @@ Collection.prototype.query = null;
2866
3060
  // Ensure instanceof works correctly
2867
3061
  // Object.setPrototypeOf(IdentifierArray.prototype, Array.prototype);
2868
3062
 
2869
- function assertRecordPassedToHasMany(record) {
3063
+ function assertRecordPassedToHasMany$1(record) {
2870
3064
  macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2871
3065
  if (!test) {
2872
3066
  throw new Error(`All elements of a hasMany relationship must be instances of Model, you passed $${typeof record}`);
@@ -2880,11 +3074,11 @@ function assertRecordPassedToHasMany(record) {
2880
3074
  }
2881
3075
  }()) : {};
2882
3076
  }
2883
- function extractIdentifierFromRecord$1(record) {
3077
+ function extractIdentifierFromRecord$2(record) {
2884
3078
  if (!record) {
2885
3079
  return null;
2886
3080
  }
2887
- assertRecordPassedToHasMany(record);
3081
+ assertRecordPassedToHasMany$1(record);
2888
3082
  return recordIdentifierFor(record);
2889
3083
  }
2890
3084
 
@@ -2979,6 +3173,9 @@ class RecordArrayManager {
2979
3173
  sync(array, pending, this._set.get(array));
2980
3174
  this._pending.delete(array);
2981
3175
  }
3176
+ mutate(mutation) {
3177
+ this.store.cache.mutate(mutation);
3178
+ }
2982
3179
 
2983
3180
  /**
2984
3181
  Get the `RecordArray` for a modelName, which contains all loaded records of
@@ -3495,6 +3692,118 @@ function constructResource(type, id, lid) {
3495
3692
  */
3496
3693
  // this import location is deprecated but breaks in 4.8 and older
3497
3694
 
3695
+ // @ts-expect-error adding to globalThis
3696
+ globalThis.setWarpDriveLogging = setLogging;
3697
+
3698
+ // @ts-expect-error adding to globalThis
3699
+ globalThis.getWarpDriveRuntimeConfig = getRuntimeConfig;
3700
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
3701
+ if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
3702
+ // @ts-expect-error adding to globalThis
3703
+ // eslint-disable-next-line
3704
+ globalThis.__WarpDriveMetricCountData = globalThis.__WarpDriveMetricCountData || {};
3705
+
3706
+ // @ts-expect-error adding to globalThis
3707
+ globalThis.getWarpDriveMetricCounts = () => {
3708
+ // @ts-expect-error
3709
+ // eslint-disable-next-line
3710
+ return structuredClone(globalThis.__WarpDriveMetricCountData);
3711
+ };
3712
+
3713
+ // @ts-expect-error adding to globalThis
3714
+ globalThis.resetWarpDriveMetricCounts = () => {
3715
+ // @ts-expect-error
3716
+ globalThis.__WarpDriveMetricCountData = {};
3717
+ };
3718
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.__INTERNAL_LOG_NATIVE_MAP_SET_COUNTS)) {
3719
+ if (getGlobalConfig().WarpDrive.debug.__INTERNAL_LOG_NATIVE_MAP_SET_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.__INTERNAL_LOG_NATIVE_MAP_SET_COUNTS) {
3720
+ // @ts-expect-error adding to globalThis
3721
+ globalThis.__primitiveInstanceId = 0;
3722
+ function interceptAndLog(klassName, methodName) {
3723
+ const klass = globalThis[klassName];
3724
+ if (methodName === 'constructor') {
3725
+ const instantiationLabel = `new ${klassName}()`;
3726
+ // @ts-expect-error
3727
+ globalThis[klassName] = class extends klass {
3728
+ // @ts-expect-error
3729
+ constructor(...args) {
3730
+ // eslint-disable-next-line
3731
+ super(...args);
3732
+ // @ts-expect-error
3733
+
3734
+ const instanceId = globalThis.__primitiveInstanceId++;
3735
+ // @ts-expect-error
3736
+ // eslint-disable-next-line
3737
+ globalThis.__WarpDriveMetricCountData[instantiationLabel] =
3738
+ // @ts-expect-error
3739
+ // eslint-disable-next-line
3740
+ (globalThis.__WarpDriveMetricCountData[instantiationLabel] || 0) + 1;
3741
+ // @ts-expect-error
3742
+ this.instanceName = `${klassName}:${instanceId} - ${new Error().stack?.split('\n')[2]}`;
3743
+ }
3744
+ };
3745
+ } else {
3746
+ // @ts-expect-error
3747
+ // eslint-disable-next-line
3748
+ const original = klass.prototype[methodName];
3749
+ const logName = `${klassName}.${methodName}`;
3750
+
3751
+ // @ts-expect-error
3752
+ klass.prototype[methodName] = function (...args) {
3753
+ // @ts-expect-error
3754
+ // eslint-disable-next-line
3755
+ globalThis.__WarpDriveMetricCountData[logName] = (globalThis.__WarpDriveMetricCountData[logName] || 0) + 1;
3756
+ // @ts-expect-error
3757
+ const {
3758
+ instanceName
3759
+ } = this;
3760
+ if (!instanceName) {
3761
+ // @ts-expect-error
3762
+ const instanceId = globalThis.__primitiveInstanceId++;
3763
+ // @ts-expect-error
3764
+ this.instanceName = `${klassName}.${methodName}:${instanceId} - ${new Error().stack?.split('\n')[2]}`;
3765
+ }
3766
+ const instanceLogName = `${logName} (${instanceName})`;
3767
+ // @ts-expect-error
3768
+ // eslint-disable-next-line
3769
+ globalThis.__WarpDriveMetricCountData[instanceLogName] =
3770
+ // @ts-expect-error
3771
+ // eslint-disable-next-line
3772
+ (globalThis.__WarpDriveMetricCountData[instanceLogName] || 0) + 1;
3773
+ // eslint-disable-next-line
3774
+ return original.apply(this, args);
3775
+ };
3776
+ }
3777
+ }
3778
+ interceptAndLog('Set', 'constructor');
3779
+ interceptAndLog('Set', 'add');
3780
+ interceptAndLog('Set', 'delete');
3781
+ interceptAndLog('Set', 'has');
3782
+ interceptAndLog('Set', 'set');
3783
+ interceptAndLog('Set', 'get');
3784
+ interceptAndLog('Map', 'constructor');
3785
+ interceptAndLog('Map', 'set');
3786
+ interceptAndLog('Map', 'delete');
3787
+ interceptAndLog('Map', 'has');
3788
+ interceptAndLog('Map', 'add');
3789
+ interceptAndLog('Map', 'get');
3790
+ interceptAndLog('WeakSet', 'constructor');
3791
+ interceptAndLog('WeakSet', 'add');
3792
+ interceptAndLog('WeakSet', 'delete');
3793
+ interceptAndLog('WeakSet', 'has');
3794
+ interceptAndLog('WeakSet', 'set');
3795
+ interceptAndLog('WeakSet', 'get');
3796
+ interceptAndLog('WeakMap', 'constructor');
3797
+ interceptAndLog('WeakMap', 'set');
3798
+ interceptAndLog('WeakMap', 'delete');
3799
+ interceptAndLog('WeakMap', 'has');
3800
+ interceptAndLog('WeakMap', 'add');
3801
+ interceptAndLog('WeakMap', 'get');
3802
+ }
3803
+ }
3804
+ }
3805
+ }
3806
+
3498
3807
  // `AwaitedKeys` is needed here to resolve any promise types like `PromiseBelongsTo`.
3499
3808
 
3500
3809
  /**
@@ -3622,12 +3931,9 @@ class Store extends BaseClass {
3622
3931
  * import Fetch from '@ember-data/request/fetch';
3623
3932
  *
3624
3933
  * class extends Store {
3625
- * constructor() {
3626
- * super(...arguments);
3627
- * this.requestManager = new RequestManager();
3628
- * this.requestManager.use([Fetch]);
3629
- * this.requestManager.useCache(CacheHandler);
3630
- * }
3934
+ * requestManager = new RequestManager()
3935
+ * .use([Fetch])
3936
+ * .useCache(CacheHandler);
3631
3937
  * }
3632
3938
  * ```
3633
3939
  *
@@ -3869,7 +4175,7 @@ class Store extends BaseClass {
3869
4175
  // the user has had the chance to set the prop.
3870
4176
  const opts = {
3871
4177
  store: this,
3872
- [EnableHydration]: true
4178
+ [EnableHydration]: requestConfig[EnableHydration] ?? true
3873
4179
  };
3874
4180
  if (requestConfig.records) {
3875
4181
  const identifierCache = this.identifierCache;
@@ -3880,22 +4186,26 @@ class Store extends BaseClass {
3880
4186
  opts.disableTestWaiter = typeof requestConfig.disableTestWaiter === 'boolean' ? requestConfig.disableTestWaiter : true;
3881
4187
  }
3882
4188
  }
3883
- if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_REQUESTS)) {
3884
- let options;
3885
- try {
3886
- options = JSON.parse(JSON.stringify(requestConfig));
3887
- } catch {
3888
- options = requestConfig;
4189
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_REQUESTS)) {
4190
+ if (getGlobalConfig().WarpDrive.debug.LOG_REQUESTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_REQUESTS) {
4191
+ let options;
4192
+ try {
4193
+ options = JSON.parse(JSON.stringify(requestConfig));
4194
+ } catch {
4195
+ options = requestConfig;
4196
+ }
4197
+ // eslint-disable-next-line no-console
4198
+ console.log(`request: [[START]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`, options);
3889
4199
  }
3890
- // eslint-disable-next-line no-console
3891
- console.log(`request: [[START]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`, options);
3892
4200
  }
3893
4201
  const request = Object.assign({}, requestConfig, opts);
3894
4202
  const future = this.requestManager.request(request);
3895
4203
  future.onFinalize(() => {
3896
- if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_REQUESTS)) {
3897
- // eslint-disable-next-line no-console
3898
- console.log(`request: [[FINALIZE]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`);
4204
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_REQUESTS)) {
4205
+ if (getGlobalConfig().WarpDrive.debug.LOG_REQUESTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_REQUESTS) {
4206
+ // eslint-disable-next-line no-console
4207
+ console.log(`request: [[FINALIZE]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`);
4208
+ }
3899
4209
  }
3900
4210
  // skip flush for legacy belongsTo
3901
4211
  if (requestConfig.op === 'findBelongsTo' && !requestConfig.url) {
@@ -4101,9 +4411,8 @@ class Store extends BaseClass {
4101
4411
  This will cause the record to be destroyed and freed up for garbage collection.
4102
4412
  Example
4103
4413
  ```javascript
4104
- store.findRecord('post', '1').then(function(post) {
4105
- store.unloadRecord(post);
4106
- });
4414
+ const { content: { data: post } } = await store.request(findRecord({ type: 'post', id: '1' }));
4415
+ store.unloadRecord(post);
4107
4416
  ```
4108
4417
  @method unloadRecord
4109
4418
  @public
@@ -5155,14 +5464,16 @@ class Store extends BaseClass {
5155
5464
  if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
5156
5465
  assertDestroyingStore(this, '_push');
5157
5466
  }
5158
- if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_PAYLOADS)) {
5159
- try {
5160
- const data = JSON.parse(JSON.stringify(jsonApiDoc));
5161
- // eslint-disable-next-line no-console
5162
- console.log('EmberData | Payload - push', data);
5163
- } catch {
5164
- // eslint-disable-next-line no-console
5165
- console.log('EmberData | Payload - push', jsonApiDoc);
5467
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_PAYLOADS)) {
5468
+ if (getGlobalConfig().WarpDrive.debug.LOG_PAYLOADS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_PAYLOADS) {
5469
+ try {
5470
+ const data = JSON.parse(JSON.stringify(jsonApiDoc));
5471
+ // eslint-disable-next-line no-console
5472
+ console.log('EmberData | Payload - push', data);
5473
+ } catch {
5474
+ // eslint-disable-next-line no-console
5475
+ console.log('EmberData | Payload - push', jsonApiDoc);
5476
+ }
5166
5477
  }
5167
5478
  }
5168
5479
  if (asyncFlush) {
@@ -5385,9 +5696,9 @@ function normalizeProperties(store, identifier, properties) {
5385
5696
  if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
5386
5697
  assertRecordsPassedToHasMany(properties[prop]);
5387
5698
  }
5388
- properties[prop] = extractIdentifiersFromRecords(properties[prop]);
5699
+ properties[prop] = extractIdentifiersFromRecords$1(properties[prop]);
5389
5700
  } else if (field.kind === 'belongsTo') {
5390
- properties[prop] = extractIdentifierFromRecord(properties[prop]);
5701
+ properties[prop] = extractIdentifierFromRecord$1(properties[prop]);
5391
5702
  }
5392
5703
  }
5393
5704
  }
@@ -5415,10 +5726,10 @@ function assertRecordsPassedToHasMany(records) {
5415
5726
  });
5416
5727
  }()) : {};
5417
5728
  }
5418
- function extractIdentifiersFromRecords(records) {
5419
- return records.map(record => extractIdentifierFromRecord(record));
5729
+ function extractIdentifiersFromRecords$1(records) {
5730
+ return records.map(record => extractIdentifierFromRecord$1(record));
5420
5731
  }
5421
- function extractIdentifierFromRecord(recordOrPromiseRecord) {
5732
+ function extractIdentifierFromRecord$1(recordOrPromiseRecord) {
5422
5733
  if (!recordOrPromiseRecord) {
5423
5734
  return null;
5424
5735
  }
@@ -6066,4 +6377,475 @@ function fetchContentAndHydrate(next, context, identifier, priority) {
6066
6377
  }]
6067
6378
  });
6068
6379
  }
6069
- 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 };
6380
+
6381
+ /**
6382
+ @module @ember-data/store
6383
+ */
6384
+ /**
6385
+ A `ManyArray` is a `MutableArray` that represents the contents of a has-many
6386
+ relationship.
6387
+
6388
+ The `ManyArray` is instantiated lazily the first time the relationship is
6389
+ requested.
6390
+
6391
+ This class is not intended to be directly instantiated by consuming applications.
6392
+
6393
+ ### Inverses
6394
+
6395
+ Often, the relationships in Ember Data applications will have
6396
+ an inverse. For example, imagine the following models are
6397
+ defined:
6398
+
6399
+ ```app/models/post.js
6400
+ import Model, { hasMany } from '@ember-data/model';
6401
+
6402
+ export default class PostModel extends Model {
6403
+ @hasMany('comment') comments;
6404
+ }
6405
+ ```
6406
+
6407
+ ```app/models/comment.js
6408
+ import Model, { belongsTo } from '@ember-data/model';
6409
+
6410
+ export default class CommentModel extends Model {
6411
+ @belongsTo('post') post;
6412
+ }
6413
+ ```
6414
+
6415
+ If you created a new instance of `Post` and added
6416
+ a `Comment` record to its `comments` has-many
6417
+ relationship, you would expect the comment's `post`
6418
+ property to be set to the post that contained
6419
+ the has-many.
6420
+
6421
+ We call the record to which a relationship belongs-to the
6422
+ relationship's _owner_.
6423
+
6424
+ @class ManyArray
6425
+ @public
6426
+ */
6427
+ class RelatedCollection extends IdentifierArray {
6428
+ /**
6429
+ The loading state of this array
6430
+ @property {Boolean} isLoaded
6431
+ @public
6432
+ */
6433
+
6434
+ /**
6435
+ `true` if the relationship is polymorphic, `false` otherwise.
6436
+ @property {Boolean} isPolymorphic
6437
+ @private
6438
+ */
6439
+
6440
+ /**
6441
+ Metadata associated with the request for async hasMany relationships.
6442
+ Example
6443
+ Given that the server returns the following JSON payload when fetching a
6444
+ hasMany relationship:
6445
+ ```js
6446
+ {
6447
+ "comments": [{
6448
+ "id": 1,
6449
+ "comment": "This is the first comment",
6450
+ }, {
6451
+ // ...
6452
+ }],
6453
+ "meta": {
6454
+ "page": 1,
6455
+ "total": 5
6456
+ }
6457
+ }
6458
+ ```
6459
+ You can then access the meta data via the `meta` property:
6460
+ ```js
6461
+ let comments = await post.comments;
6462
+ let meta = comments.meta;
6463
+ // meta.page => 1
6464
+ // meta.total => 5
6465
+ ```
6466
+ @property {Object | null} meta
6467
+ @public
6468
+ */
6469
+
6470
+ /**
6471
+ * Retrieve the links for this relationship
6472
+ *
6473
+ @property {Object | null} links
6474
+ @public
6475
+ */
6476
+
6477
+ constructor(options) {
6478
+ super(options);
6479
+ this.isLoaded = options.isLoaded || false;
6480
+ this.isAsync = options.isAsync || false;
6481
+ this.isPolymorphic = options.isPolymorphic || false;
6482
+ this.identifier = options.identifier;
6483
+ this.key = options.key;
6484
+ }
6485
+ [MUTATE](target, receiver, prop, args, _SIGNAL) {
6486
+ switch (prop) {
6487
+ case 'length 0':
6488
+ {
6489
+ Reflect.set(target, 'length', 0);
6490
+ mutateReplaceRelatedRecords(this, [], _SIGNAL);
6491
+ return true;
6492
+ }
6493
+ case 'replace cell':
6494
+ {
6495
+ const [index, prior, value] = args;
6496
+ target[index] = value;
6497
+ mutateReplaceRelatedRecord(this, {
6498
+ value,
6499
+ prior,
6500
+ index
6501
+ }, _SIGNAL);
6502
+ return true;
6503
+ }
6504
+ case 'push':
6505
+ {
6506
+ const newValues = extractIdentifiersFromRecords(args);
6507
+ assertNoDuplicates(this, target, currentState => currentState.push(...newValues), `Cannot push duplicates to a hasMany's state.`);
6508
+ if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
6509
+ // dedupe
6510
+ const seen = new Set(target);
6511
+ const unique = new Set();
6512
+ args.forEach(item => {
6513
+ const identifier = recordIdentifierFor(item);
6514
+ if (!seen.has(identifier)) {
6515
+ seen.add(identifier);
6516
+ unique.add(item);
6517
+ }
6518
+ });
6519
+ const newArgs = Array.from(unique);
6520
+ const result = Reflect.apply(target[prop], receiver, newArgs);
6521
+ if (newArgs.length) {
6522
+ mutateAddToRelatedRecords(this, {
6523
+ value: extractIdentifiersFromRecords(newArgs)
6524
+ }, _SIGNAL);
6525
+ }
6526
+ return result;
6527
+ }
6528
+
6529
+ // else, no dedupe, error on duplicates
6530
+ const result = Reflect.apply(target[prop], receiver, args);
6531
+ if (newValues.length) {
6532
+ mutateAddToRelatedRecords(this, {
6533
+ value: newValues
6534
+ }, _SIGNAL);
6535
+ }
6536
+ return result;
6537
+ }
6538
+ case 'pop':
6539
+ {
6540
+ const result = Reflect.apply(target[prop], receiver, args);
6541
+ if (result) {
6542
+ mutateRemoveFromRelatedRecords(this, {
6543
+ value: recordIdentifierFor(result)
6544
+ }, _SIGNAL);
6545
+ }
6546
+ return result;
6547
+ }
6548
+ case 'unshift':
6549
+ {
6550
+ const newValues = extractIdentifiersFromRecords(args);
6551
+ assertNoDuplicates(this, target, currentState => currentState.unshift(...newValues), `Cannot unshift duplicates to a hasMany's state.`);
6552
+ if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
6553
+ // dedupe
6554
+ const seen = new Set(target);
6555
+ const unique = new Set();
6556
+ args.forEach(item => {
6557
+ const identifier = recordIdentifierFor(item);
6558
+ if (!seen.has(identifier)) {
6559
+ seen.add(identifier);
6560
+ unique.add(item);
6561
+ }
6562
+ });
6563
+ const newArgs = Array.from(unique);
6564
+ const result = Reflect.apply(target[prop], receiver, newArgs);
6565
+ if (newArgs.length) {
6566
+ mutateAddToRelatedRecords(this, {
6567
+ value: extractIdentifiersFromRecords(newArgs),
6568
+ index: 0
6569
+ }, _SIGNAL);
6570
+ }
6571
+ return result;
6572
+ }
6573
+
6574
+ // else, no dedupe, error on duplicates
6575
+ const result = Reflect.apply(target[prop], receiver, args);
6576
+ if (newValues.length) {
6577
+ mutateAddToRelatedRecords(this, {
6578
+ value: newValues,
6579
+ index: 0
6580
+ }, _SIGNAL);
6581
+ }
6582
+ return result;
6583
+ }
6584
+ case 'shift':
6585
+ {
6586
+ const result = Reflect.apply(target[prop], receiver, args);
6587
+ if (result) {
6588
+ mutateRemoveFromRelatedRecords(this, {
6589
+ value: recordIdentifierFor(result),
6590
+ index: 0
6591
+ }, _SIGNAL);
6592
+ }
6593
+ return result;
6594
+ }
6595
+ case 'sort':
6596
+ {
6597
+ const result = Reflect.apply(target[prop], receiver, args);
6598
+ mutateSortRelatedRecords(this, result.map(recordIdentifierFor), _SIGNAL);
6599
+ return result;
6600
+ }
6601
+ case 'splice':
6602
+ {
6603
+ const [start, deleteCount, ...adds] = args;
6604
+
6605
+ // detect a full replace
6606
+ if (start === 0 && deleteCount === this[SOURCE].length) {
6607
+ const newValues = extractIdentifiersFromRecords(adds);
6608
+ assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot replace a hasMany's state with a new state that contains duplicates.`);
6609
+ if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
6610
+ // dedupe
6611
+ const current = new Set(adds);
6612
+ const unique = Array.from(current);
6613
+ const newArgs = [start, deleteCount].concat(unique);
6614
+ const result = Reflect.apply(target[prop], receiver, newArgs);
6615
+ mutateReplaceRelatedRecords(this, extractIdentifiersFromRecords(unique), _SIGNAL);
6616
+ return result;
6617
+ }
6618
+
6619
+ // else, no dedupe, error on duplicates
6620
+ const result = Reflect.apply(target[prop], receiver, args);
6621
+ mutateReplaceRelatedRecords(this, newValues, _SIGNAL);
6622
+ return result;
6623
+ }
6624
+ const newValues = extractIdentifiersFromRecords(adds);
6625
+ assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot splice a hasMany's state with a new state that contains duplicates.`);
6626
+ if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
6627
+ // dedupe
6628
+ const currentState = target.slice();
6629
+ currentState.splice(start, deleteCount);
6630
+ const seen = new Set(currentState);
6631
+ const unique = [];
6632
+ adds.forEach(item => {
6633
+ const identifier = recordIdentifierFor(item);
6634
+ if (!seen.has(identifier)) {
6635
+ seen.add(identifier);
6636
+ unique.push(item);
6637
+ }
6638
+ });
6639
+ const newArgs = [start, deleteCount, ...unique];
6640
+ const result = Reflect.apply(target[prop], receiver, newArgs);
6641
+ if (deleteCount > 0) {
6642
+ mutateRemoveFromRelatedRecords(this, {
6643
+ value: result.map(recordIdentifierFor),
6644
+ index: start
6645
+ }, _SIGNAL);
6646
+ }
6647
+ if (unique.length > 0) {
6648
+ mutateAddToRelatedRecords(this, {
6649
+ value: extractIdentifiersFromRecords(unique),
6650
+ index: start
6651
+ }, _SIGNAL);
6652
+ }
6653
+ return result;
6654
+ }
6655
+
6656
+ // else, no dedupe, error on duplicates
6657
+ const result = Reflect.apply(target[prop], receiver, args);
6658
+ if (deleteCount > 0) {
6659
+ mutateRemoveFromRelatedRecords(this, {
6660
+ value: result.map(recordIdentifierFor),
6661
+ index: start
6662
+ }, _SIGNAL);
6663
+ }
6664
+ if (newValues.length > 0) {
6665
+ mutateAddToRelatedRecords(this, {
6666
+ value: newValues,
6667
+ index: start
6668
+ }, _SIGNAL);
6669
+ }
6670
+ return result;
6671
+ }
6672
+ default:
6673
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
6674
+ {
6675
+ throw new Error(`unable to convert ${prop} into a transaction that updates the cache state for this record array`);
6676
+ }
6677
+ })() : {};
6678
+ }
6679
+ }
6680
+ notify() {
6681
+ const signal = this[ARRAY_SIGNAL];
6682
+ signal.shouldReset = true;
6683
+ notifyArray(this);
6684
+ }
6685
+
6686
+ /**
6687
+ Reloads all of the records in the manyArray. If the manyArray
6688
+ holds a relationship that was originally fetched using a links url
6689
+ EmberData will revisit the original links url to repopulate the
6690
+ relationship.
6691
+ If the ManyArray holds the result of a `store.query()` reload will
6692
+ re-run the original query.
6693
+ Example
6694
+ ```javascript
6695
+ let user = store.peekRecord('user', '1')
6696
+ await login(user);
6697
+ let permissions = await user.permissions;
6698
+ await permissions.reload();
6699
+ ```
6700
+ @method reload
6701
+ @public
6702
+ */
6703
+ reload(options) {
6704
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
6705
+ if (!test) {
6706
+ throw new Error(`Expected the manager for ManyArray to implement reloadHasMany`);
6707
+ }
6708
+ })(typeof this._manager.reloadHasMany === 'function') : {};
6709
+ // TODO this is odd, we don't ask the store for anything else like this?
6710
+ return this._manager.reloadHasMany(this.key, options);
6711
+ }
6712
+
6713
+ /**
6714
+ Saves all of the records in the `ManyArray`.
6715
+ Note: this API can only be used in legacy mode with a configured Adapter.
6716
+ Example
6717
+ ```javascript
6718
+ const { content: { data: inbox } } = await store.request(findRecord({ type: 'inbox', id: '1' }));
6719
+ let messages = await inbox.messages;
6720
+ messages.forEach((message) => {
6721
+ message.isRead = true;
6722
+ });
6723
+ messages.save();
6724
+ ```
6725
+ @method save
6726
+ @public
6727
+ @return {PromiseArray} promise
6728
+ */
6729
+
6730
+ /**
6731
+ Create a child record within the owner
6732
+ @method createRecord
6733
+ @public
6734
+ @param {Object} hash
6735
+ @return {Model} record
6736
+ */
6737
+ createRecord(hash) {
6738
+ const {
6739
+ store
6740
+ } = this;
6741
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
6742
+ if (!test) {
6743
+ throw new Error(`Expected modelName to be set`);
6744
+ }
6745
+ })(this.modelName) : {};
6746
+ const record = store.createRecord(this.modelName, hash);
6747
+ this.push(record);
6748
+ return record;
6749
+ }
6750
+ destroy() {
6751
+ super.destroy(false);
6752
+ }
6753
+ }
6754
+ RelatedCollection.prototype.isAsync = false;
6755
+ RelatedCollection.prototype.isPolymorphic = false;
6756
+ RelatedCollection.prototype.identifier = null;
6757
+ RelatedCollection.prototype.cache = null;
6758
+ RelatedCollection.prototype._inverseIsAsync = false;
6759
+ RelatedCollection.prototype.key = '';
6760
+ RelatedCollection.prototype.DEPRECATED_CLASS_NAME = 'ManyArray';
6761
+ function assertRecordPassedToHasMany(record) {
6762
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
6763
+ if (!test) {
6764
+ throw new Error(`All elements of a hasMany relationship must be instances of Model, you passed ${typeof record}`);
6765
+ }
6766
+ })(function () {
6767
+ try {
6768
+ recordIdentifierFor(record);
6769
+ return true;
6770
+ } catch {
6771
+ return false;
6772
+ }
6773
+ }()) : {};
6774
+ }
6775
+ function extractIdentifiersFromRecords(records) {
6776
+ return records.map(extractIdentifierFromRecord);
6777
+ }
6778
+ function extractIdentifierFromRecord(recordOrPromiseRecord) {
6779
+ assertRecordPassedToHasMany(recordOrPromiseRecord);
6780
+ return recordIdentifierFor(recordOrPromiseRecord);
6781
+ }
6782
+ function assertNoDuplicates(collection, target, callback, reason) {
6783
+ const state = target.slice();
6784
+ callback(state);
6785
+ if (state.length !== new Set(state).size) {
6786
+ const duplicates = state.filter((currentValue, currentIndex) => state.indexOf(currentValue) !== currentIndex);
6787
+ if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
6788
+ 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, {
6789
+ id: 'ember-data:deprecate-many-array-duplicates',
6790
+ for: 'ember-data',
6791
+ until: '6.0',
6792
+ since: {
6793
+ enabled: '5.3',
6794
+ available: '4.13'
6795
+ }
6796
+ });
6797
+ } else {
6798
+ 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- ')}`);
6799
+ }
6800
+ }
6801
+ }
6802
+ function mutateAddToRelatedRecords(collection, operationInfo, _SIGNAL) {
6803
+ mutate(collection, {
6804
+ op: 'addToRelatedRecords',
6805
+ record: collection.identifier,
6806
+ field: collection.key,
6807
+ ...operationInfo
6808
+ }, _SIGNAL);
6809
+ }
6810
+ function mutateRemoveFromRelatedRecords(collection, operationInfo, _SIGNAL) {
6811
+ mutate(collection, {
6812
+ op: 'removeFromRelatedRecords',
6813
+ record: collection.identifier,
6814
+ field: collection.key,
6815
+ ...operationInfo
6816
+ }, _SIGNAL);
6817
+ }
6818
+ function mutateReplaceRelatedRecord(collection, operationInfo, _SIGNAL) {
6819
+ mutate(collection, {
6820
+ op: 'replaceRelatedRecord',
6821
+ record: collection.identifier,
6822
+ field: collection.key,
6823
+ ...operationInfo
6824
+ }, _SIGNAL);
6825
+ }
6826
+ function mutateReplaceRelatedRecords(collection, value, _SIGNAL) {
6827
+ mutate(collection, {
6828
+ op: 'replaceRelatedRecords',
6829
+ record: collection.identifier,
6830
+ field: collection.key,
6831
+ value
6832
+ }, _SIGNAL);
6833
+ }
6834
+ function mutateSortRelatedRecords(collection, value, _SIGNAL) {
6835
+ mutate(collection, {
6836
+ op: 'sortRelatedRecords',
6837
+ record: collection.identifier,
6838
+ field: collection.key,
6839
+ value
6840
+ }, _SIGNAL);
6841
+ }
6842
+ function mutate(collection, mutation, _SIGNAL) {
6843
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
6844
+ if (!test) {
6845
+ throw new Error(`Expected the manager for ManyArray to implement mutate`);
6846
+ }
6847
+ })(typeof collection._manager.mutate === 'function') : {};
6848
+ collection._manager.mutate(mutation);
6849
+ addToTransaction(_SIGNAL);
6850
+ }
6851
+ 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 };