@ember-data/store 5.4.0-beta.4 → 5.4.0-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +8 -0
  2. package/addon-main.cjs +5 -0
  3. package/dist/-private.js +1 -0
  4. package/{addon/cache-handler-XLbbNJdo.js → dist/cache-handler-C5ilAUZ5.js} +1140 -657
  5. package/dist/cache-handler-C5ilAUZ5.js.map +1 -0
  6. package/{addon → dist}/index.js +4 -1
  7. package/{addon → dist}/index.js.map +1 -1
  8. package/dist/types.js +0 -0
  9. package/dist/types.js.map +1 -0
  10. package/package.json +48 -51
  11. package/unstable-preview-types/-private/cache-handler.d.ts +144 -0
  12. package/unstable-preview-types/-private/cache-handler.d.ts.map +1 -0
  13. package/unstable-preview-types/-private/caches/cache-utils.d.ts +11 -0
  14. package/unstable-preview-types/-private/caches/cache-utils.d.ts.map +1 -0
  15. package/unstable-preview-types/-private/caches/identifier-cache.d.ts +176 -0
  16. package/unstable-preview-types/-private/caches/identifier-cache.d.ts.map +1 -0
  17. package/unstable-preview-types/-private/caches/instance-cache.d.ts +61 -0
  18. package/unstable-preview-types/-private/caches/instance-cache.d.ts.map +1 -0
  19. package/unstable-preview-types/-private/caches/resource-utils.d.ts +12 -0
  20. package/unstable-preview-types/-private/caches/resource-utils.d.ts.map +1 -0
  21. package/unstable-preview-types/-private/document.d.ts +146 -0
  22. package/unstable-preview-types/-private/document.d.ts.map +1 -0
  23. package/unstable-preview-types/-private/legacy-model-support/record-reference.d.ts +179 -0
  24. package/unstable-preview-types/-private/legacy-model-support/record-reference.d.ts.map +1 -0
  25. package/unstable-preview-types/-private/legacy-model-support/shim-model-class.d.ts +19 -0
  26. package/unstable-preview-types/-private/legacy-model-support/shim-model-class.d.ts.map +1 -0
  27. package/unstable-preview-types/-private/managers/cache-capabilities-manager.d.ts +31 -0
  28. package/unstable-preview-types/-private/managers/cache-capabilities-manager.d.ts.map +1 -0
  29. package/unstable-preview-types/-private/managers/cache-manager.d.ts +441 -0
  30. package/unstable-preview-types/-private/managers/cache-manager.d.ts.map +1 -0
  31. package/unstable-preview-types/-private/managers/notification-manager.d.ts +96 -0
  32. package/unstable-preview-types/-private/managers/notification-manager.d.ts.map +1 -0
  33. package/unstable-preview-types/-private/managers/record-array-manager.d.ts +97 -0
  34. package/unstable-preview-types/-private/managers/record-array-manager.d.ts.map +1 -0
  35. package/unstable-preview-types/-private/network/request-cache.d.ts +109 -0
  36. package/unstable-preview-types/-private/network/request-cache.d.ts.map +1 -0
  37. package/unstable-preview-types/-private/record-arrays/identifier-array.d.ts +138 -0
  38. package/unstable-preview-types/-private/record-arrays/identifier-array.d.ts.map +1 -0
  39. package/unstable-preview-types/-private/record-arrays/native-proxy-type-fix.d.ts +118 -0
  40. package/unstable-preview-types/-private/record-arrays/native-proxy-type-fix.d.ts.map +1 -0
  41. package/unstable-preview-types/-private/store-service.d.ts +1522 -0
  42. package/unstable-preview-types/-private/store-service.d.ts.map +1 -0
  43. package/unstable-preview-types/-private/store-service.type-test.d.ts +4 -0
  44. package/unstable-preview-types/-private/store-service.type-test.d.ts.map +1 -0
  45. package/unstable-preview-types/-private/utils/coerce-id.d.ts +10 -0
  46. package/unstable-preview-types/-private/utils/coerce-id.d.ts.map +1 -0
  47. package/unstable-preview-types/-private/utils/construct-resource.d.ts +9 -0
  48. package/unstable-preview-types/-private/utils/construct-resource.d.ts.map +1 -0
  49. package/unstable-preview-types/-private/utils/is-non-empty-string.d.ts +4 -0
  50. package/unstable-preview-types/-private/utils/is-non-empty-string.d.ts.map +1 -0
  51. package/unstable-preview-types/-private/utils/normalize-model-name.d.ts +4 -0
  52. package/unstable-preview-types/-private/utils/normalize-model-name.d.ts.map +1 -0
  53. package/unstable-preview-types/-private/utils/uuid-polyfill.d.ts +4 -0
  54. package/unstable-preview-types/-private/utils/uuid-polyfill.d.ts.map +1 -0
  55. package/unstable-preview-types/-private.d.ts +25 -0
  56. package/unstable-preview-types/-private.d.ts.map +1 -0
  57. package/unstable-preview-types/-types/overview.d.ts +21 -0
  58. package/unstable-preview-types/-types/overview.d.ts.map +1 -0
  59. package/unstable-preview-types/-types/q/cache-capabilities-manager.d.ts +109 -0
  60. package/unstable-preview-types/-types/q/cache-capabilities-manager.d.ts.map +1 -0
  61. package/unstable-preview-types/-types/q/ds-model.d.ts +25 -0
  62. package/unstable-preview-types/-types/q/ds-model.d.ts.map +1 -0
  63. package/unstable-preview-types/-types/q/identifier.d.ts +193 -0
  64. package/unstable-preview-types/-types/q/identifier.d.ts.map +1 -0
  65. package/unstable-preview-types/-types/q/promise-proxies.d.ts +4 -0
  66. package/unstable-preview-types/-types/q/promise-proxies.d.ts.map +1 -0
  67. package/unstable-preview-types/-types/q/record-data-json-api.d.ts +36 -0
  68. package/unstable-preview-types/-types/q/record-data-json-api.d.ts.map +1 -0
  69. package/unstable-preview-types/-types/q/record-instance.d.ts +29 -0
  70. package/unstable-preview-types/-types/q/record-instance.d.ts.map +1 -0
  71. package/unstable-preview-types/-types/q/schema-service.d.ts +358 -0
  72. package/unstable-preview-types/-types/q/schema-service.d.ts.map +1 -0
  73. package/unstable-preview-types/-types/q/store.d.ts +38 -0
  74. package/unstable-preview-types/-types/q/store.d.ts.map +1 -0
  75. package/unstable-preview-types/index.d.ts +222 -0
  76. package/unstable-preview-types/index.d.ts.map +1 -0
  77. package/unstable-preview-types/types.d.ts +7 -0
  78. package/unstable-preview-types/types.d.ts.map +1 -0
  79. package/addon/-private.js +0 -1
  80. package/addon/cache-handler-XLbbNJdo.js.map +0 -1
  81. package/addon-main.js +0 -93
  82. /package/{addon → dist}/-private.js.map +0 -0
@@ -1,10 +1,10 @@
1
- import { deprecate, assert, warn } from '@ember/debug';
2
- import EmberObject from '@ember/object';
1
+ import { deprecate, warn } from '@ember/debug';
2
+ import { macroCondition, getGlobalConfig, dependencySatisfies, importSync } from '@embroider/macros';
3
3
  import { SkipCache, EnableHydration } from '@warp-drive/core-types/request';
4
- import { macroCondition, getOwnConfig } from '@embroider/macros';
4
+ import { getOrSetGlobal, setTransient, peekTransient } from '@warp-drive/core-types/-private';
5
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/string';
7
- import { defineSignal, addToTransaction, createSignal, subscribe, createArrayTags, addTransactionCB } from '@ember-data/tracking/-private';
6
+ import { dasherize } from '@ember-data/request-utils/string';
7
+ import { defineSignal, createSignal, subscribe, createArrayTags, addToTransaction, addTransactionCB } from '@ember-data/tracking/-private';
8
8
  import { _backburner } from '@ember/runloop';
9
9
  import { compat } from '@ember-data/tracking';
10
10
 
@@ -13,7 +13,7 @@ import { compat } from '@ember-data/tracking';
13
13
  */
14
14
 
15
15
  function coerceId(id) {
16
- if (macroCondition(getOwnConfig().deprecations.DEPRECATE_NON_STRICT_ID)) {
16
+ if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_NON_STRICT_ID)) {
17
17
  let normalized;
18
18
  if (id === null || id === undefined || id === '') {
19
19
  normalized = null;
@@ -31,7 +31,11 @@ function coerceId(id) {
31
31
  });
32
32
  return normalized;
33
33
  }
34
- assert(`Resource IDs must be a non-empty string or null. Received '${String(id)}'.`, id === null || typeof id === 'string' && id.length > 0);
34
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
35
+ if (!test) {
36
+ throw new Error(`Resource IDs must be a non-empty string or null. Received '${String(id)}'.`);
37
+ }
38
+ })(id === null || typeof id === 'string' && id.length > 0) : {};
35
39
  return id;
36
40
  }
37
41
  function ensureStringId(id) {
@@ -41,11 +45,15 @@ function ensureStringId(id) {
41
45
  } else if (typeof id === 'number' && !isNaN(id)) {
42
46
  normalized = String(id);
43
47
  }
44
- assert(`Expected id to be a string or number, received ${String(id)}`, normalized !== null);
48
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
49
+ if (!test) {
50
+ throw new Error(`Expected id to be a string or number, received ${String(id)}`);
51
+ }
52
+ })(normalized !== null) : {};
45
53
  return normalized;
46
54
  }
47
55
  function normalizeModelName(type) {
48
- if (macroCondition(getOwnConfig().deprecations.DEPRECATE_NON_STRICT_TYPES)) {
56
+ if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_NON_STRICT_TYPES)) {
49
57
  const result = dasherize(type);
50
58
  deprecate(`The resource type '${type}' is not normalized. Update your application code to use '${result}' instead of '${type}'.`, result === type, {
51
59
  id: 'ember-data:deprecate-non-strict-types',
@@ -121,8 +129,8 @@ function hasType(resource) {
121
129
  /**
122
130
  @module @ember-data/store
123
131
  */
124
- const IDENTIFIERS = new Set();
125
- const DOCUMENTS = new Set();
132
+ const IDENTIFIERS = getOrSetGlobal('IDENTIFIERS', new Set());
133
+ const DOCUMENTS = getOrSetGlobal('DOCUMENTS', new Set());
126
134
  function isStableIdentifier(identifier) {
127
135
  return identifier[CACHE_OWNER] !== undefined || IDENTIFIERS.has(identifier);
128
136
  }
@@ -131,11 +139,15 @@ function isDocumentIdentifier(identifier) {
131
139
  }
132
140
  const isFastBoot = typeof FastBoot !== 'undefined';
133
141
  const _crypto = isFastBoot ? FastBoot.require('crypto') : window.crypto;
134
- if (macroCondition(getOwnConfig().polyfillUUID)) {
142
+ if (macroCondition(getGlobalConfig().WarpDrive.polyfillUUID)) {
135
143
  installPolyfill();
136
144
  }
137
145
  function uuidv4() {
138
- assert('crypto.randomUUID needs to be avaliable. Some browsers incorrectly disallow it in insecure contexts. You maybe want to enable the polyfill: https://github.com/emberjs/data#randomuuid-polyfill', typeof _crypto.randomUUID === 'function');
146
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
147
+ if (!test) {
148
+ throw new Error('crypto.randomUUID needs to be avaliable. Some browsers incorrectly disallow it in insecure contexts. You maybe want to enable the polyfill: https://github.com/emberjs/data#randomuuid-polyfill');
149
+ }
150
+ })(typeof _crypto.randomUUID === 'function') : {};
139
151
  return _crypto.randomUUID();
140
152
  }
141
153
  function freeze(obj) {
@@ -148,26 +160,27 @@ function freeze(obj) {
148
160
  // type IdentifierTypeLookup = { all: Set<StableRecordIdentifier>; id: Map<string, StableRecordIdentifier> };
149
161
  // type IdentifiersByType = Map<string, IdentifierTypeLookup>;
150
162
 
151
- let configuredForgetMethod;
152
- let configuredGenerationMethod;
153
- let configuredResetMethod;
154
- let configuredUpdateMethod;
155
163
  function setIdentifierGenerationMethod(method) {
156
- configuredGenerationMethod = method;
164
+ setTransient('configuredGenerationMethod', method);
157
165
  }
158
166
  function setIdentifierUpdateMethod(method) {
159
- configuredUpdateMethod = method;
167
+ setTransient('configuredUpdateMethod', method);
160
168
  }
161
169
  function setIdentifierForgetMethod(method) {
162
- configuredForgetMethod = method;
170
+ setTransient('configuredForgetMethod', method);
163
171
  }
164
172
  function setIdentifierResetMethod(method) {
165
- configuredResetMethod = method;
173
+ setTransient('configuredResetMethod', method);
174
+ }
175
+ function setKeyInfoForResource(method) {
176
+ setTransient('configuredKeyInfoMethod', method);
166
177
  }
167
178
 
168
179
  // Map<type, Map<id, lid>>
169
180
 
181
+ // TODO can we just delete this?
170
182
  const NEW_IDENTIFIERS = new Map();
183
+ // TODO @runspired maybe needs peekTransient ?
171
184
  let IDENTIFIER_CACHE_ID = 0;
172
185
  function updateTypeIdMapping(typeMap, identifier, id) {
173
186
  let idMap = typeMap.get(identifier.type);
@@ -179,7 +192,11 @@ function updateTypeIdMapping(typeMap, identifier, id) {
179
192
  }
180
193
  function defaultUpdateMethod(identifier, data, bucket) {
181
194
  if (bucket === 'record') {
182
- assert(`Expected identifier to be a StableRecordIdentifier`, isStableIdentifier(identifier));
195
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
196
+ if (!test) {
197
+ throw new Error(`Expected identifier to be a StableRecordIdentifier`);
198
+ }
199
+ })(isStableIdentifier(identifier)) : {};
183
200
  if (!identifier.id && hasId(data)) {
184
201
  updateTypeIdMapping(NEW_IDENTIFIERS, identifier, data.id);
185
202
  }
@@ -189,7 +206,11 @@ function defaultKeyInfoMethod(resource, known) {
189
206
  // TODO RFC something to make this configurable
190
207
  const id = hasId(resource) ? coerceId(resource.id) : null;
191
208
  const type = hasType(resource) ? normalizeModelName(resource.type) : known ? known.type : null;
192
- assert(`Expected keyInfoForResource to provide a type for the resource`, type);
209
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
210
+ if (!test) {
211
+ throw new Error(`Expected keyInfoForResource to provide a type for the resource`);
212
+ }
213
+ })(type) : {};
193
214
  return {
194
215
  type,
195
216
  id
@@ -200,7 +221,11 @@ function defaultGenerationMethod(data, bucket) {
200
221
  if (hasLid(data)) {
201
222
  return data.lid;
202
223
  }
203
- assert(`Cannot generate an identifier for a resource without a type`, hasType(data));
224
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
225
+ if (!test) {
226
+ throw new Error(`Cannot generate an identifier for a resource without a type`);
227
+ }
228
+ })(hasType(data)) : {};
204
229
  if (hasId(data)) {
205
230
  const type = normalizeModelName(data.type);
206
231
  const lid = NEW_IDENTIFIERS.get(type)?.get(data.id);
@@ -216,15 +241,19 @@ function defaultGenerationMethod(data, bucket) {
216
241
  }
217
242
  return null;
218
243
  }
219
- assert(`Unknown bucket ${bucket}`, false);
244
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
245
+ {
246
+ throw new Error(`Unknown bucket ${bucket}`);
247
+ }
248
+ })() : {};
220
249
  }
221
250
  function defaultEmptyCallback(...args) {}
222
251
  function defaultMergeMethod(a, _b, _c) {
223
252
  return a;
224
253
  }
225
254
  let DEBUG_MAP;
226
- if (macroCondition(getOwnConfig().env.DEBUG)) {
227
- DEBUG_MAP = new WeakMap();
255
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
256
+ DEBUG_MAP = getOrSetGlobal('DEBUG_MAP', new WeakMap());
228
257
  }
229
258
 
230
259
  /**
@@ -244,13 +273,12 @@ class IdentifierCache {
244
273
  constructor() {
245
274
  // we cache the user configuredGenerationMethod at init because it must
246
275
  // be configured prior and is not allowed to be changed
247
- this._generate = configuredGenerationMethod || defaultGenerationMethod;
248
- this._update = configuredUpdateMethod || defaultUpdateMethod;
249
- this._forget = configuredForgetMethod || defaultEmptyCallback;
250
- this._reset = configuredResetMethod || defaultEmptyCallback;
276
+ this._generate = peekTransient('configuredGenerationMethod') || defaultGenerationMethod;
277
+ this._update = peekTransient('configuredUpdateMethod') || defaultUpdateMethod;
278
+ this._forget = peekTransient('configuredForgetMethod') || defaultEmptyCallback;
279
+ this._reset = peekTransient('configuredResetMethod') || defaultEmptyCallback;
251
280
  this._merge = defaultMergeMethod;
252
- this._keyInfoForResource = defaultKeyInfoMethod;
253
- this._isDefaultConfig = !configuredGenerationMethod;
281
+ this._keyInfoForResource = peekTransient('configuredKeyInfoMethod') || defaultKeyInfoMethod;
254
282
  this._id = IDENTIFIER_CACHE_ID++;
255
283
  this._cache = {
256
284
  resources: new Map(),
@@ -282,19 +310,19 @@ class IdentifierCache {
282
310
  */
283
311
 
284
312
  _getRecordIdentifier(resource, shouldGenerate) {
285
- if (macroCondition(getOwnConfig().debug.LOG_IDENTIFIERS)) {
313
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS)) {
286
314
  // eslint-disable-next-line no-console
287
315
  console.groupCollapsed(`Identifiers: ${shouldGenerate ? 'Generating' : 'Peeking'} Identifier`, resource);
288
316
  }
289
317
  // short circuit if we're already the stable version
290
318
  if (isStableIdentifier(resource)) {
291
- if (macroCondition(getOwnConfig().env.DEBUG)) {
319
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
292
320
  // TODO should we instead just treat this case as a new generation skipping the short circuit?
293
321
  if (!this._cache.resources.has(resource.lid) || this._cache.resources.get(resource.lid) !== resource) {
294
322
  throw new Error(`The supplied identifier ${JSON.stringify(resource)} does not belong to this store instance`);
295
323
  }
296
324
  }
297
- if (macroCondition(getOwnConfig().debug.LOG_IDENTIFIERS)) {
325
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS)) {
298
326
  // eslint-disable-next-line no-console
299
327
  console.log(`Identifiers: cache HIT - Stable ${resource.lid}`);
300
328
  // eslint-disable-next-line no-console
@@ -305,20 +333,20 @@ class IdentifierCache {
305
333
 
306
334
  // the resource is unknown, ask the application to identify this data for us
307
335
  const lid = this._generate(resource, 'record');
308
- if (macroCondition(getOwnConfig().debug.LOG_IDENTIFIERS)) {
336
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS)) {
309
337
  // eslint-disable-next-line no-console
310
338
  console.log(`Identifiers: ${lid ? 'no ' : ''}lid ${lid ? lid + ' ' : ''}determined for resource`, resource);
311
339
  }
312
340
  let identifier = /*#__NOINLINE__*/getIdentifierFromLid(this._cache, lid, resource);
313
341
  if (identifier !== null) {
314
- if (macroCondition(getOwnConfig().debug.LOG_IDENTIFIERS)) {
342
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS)) {
315
343
  // eslint-disable-next-line no-console
316
344
  console.groupEnd();
317
345
  }
318
346
  return identifier;
319
347
  }
320
348
  if (shouldGenerate === 0) {
321
- if (macroCondition(getOwnConfig().debug.LOG_IDENTIFIERS)) {
349
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS)) {
322
350
  // eslint-disable-next-line no-console
323
351
  console.groupEnd();
324
352
  }
@@ -338,7 +366,7 @@ class IdentifierCache {
338
366
  identifier = /*#__NOINLINE__*/makeStableRecordIdentifier(keyInfo, 'record', false);
339
367
  }
340
368
  addResourceToCache(this._cache, identifier);
341
- if (macroCondition(getOwnConfig().debug.LOG_IDENTIFIERS)) {
369
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS)) {
342
370
  // eslint-disable-next-line no-console
343
371
  console.groupEnd();
344
372
  }
@@ -380,7 +408,7 @@ class IdentifierCache {
380
408
  identifier = {
381
409
  lid: cacheKey
382
410
  };
383
- if (macroCondition(getOwnConfig().env.DEBUG)) {
411
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
384
412
  Object.freeze(identifier);
385
413
  }
386
414
  DOCUMENTS.add(identifier);
@@ -426,7 +454,7 @@ class IdentifierCache {
426
454
  }, 'record', true);
427
455
 
428
456
  // populate our unique table
429
- if (macroCondition(getOwnConfig().env.DEBUG)) {
457
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
430
458
  if (this._cache.resources.has(identifier.lid)) {
431
459
  throw new Error(`The lid generated for the new record is not unique as it matches an existing identifier`);
432
460
  }
@@ -434,7 +462,7 @@ class IdentifierCache {
434
462
 
435
463
  /*#__NOINLINE__*/
436
464
  addResourceToCache(this._cache, identifier);
437
- if (macroCondition(getOwnConfig().debug.LOG_IDENTIFIERS)) {
465
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS)) {
438
466
  // eslint-disable-next-line no-console
439
467
  console.log(`Identifiers: created identifier ${String(identifier)} for newly generated resource`, data);
440
468
  }
@@ -483,7 +511,7 @@ class IdentifierCache {
483
511
  if (hadLid) {
484
512
  data.lid = identifier.lid;
485
513
  }
486
- if (macroCondition(getOwnConfig().debug.LOG_IDENTIFIERS)) {
514
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS)) {
487
515
  // eslint-disable-next-line no-console
488
516
  console.log(`Identifiers: merged identifiers ${generatedIdentifier.lid} and ${existingIdentifier.lid} for resource into ${identifier.lid}`, data);
489
517
  }
@@ -495,17 +523,21 @@ class IdentifierCache {
495
523
 
496
524
  // add to our own secondary lookup table
497
525
  if (id !== newId && newId !== null) {
498
- if (macroCondition(getOwnConfig().debug.LOG_IDENTIFIERS)) {
526
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS)) {
499
527
  // eslint-disable-next-line no-console
500
528
  console.log(`Identifiers: updated id for identifier ${identifier.lid} from '${String(id)}' to '${String(newId)}' for resource`, data);
501
529
  }
502
530
  const typeSet = this._cache.resourcesByType[identifier.type];
503
- assert(`Expected to find a typeSet for ${identifier.type}`, typeSet);
531
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
532
+ if (!test) {
533
+ throw new Error(`Expected to find a typeSet for ${identifier.type}`);
534
+ }
535
+ })(typeSet) : {};
504
536
  typeSet.id.set(newId, identifier);
505
537
  if (id !== null) {
506
538
  typeSet.id.delete(id);
507
539
  }
508
- } else if (macroCondition(getOwnConfig().debug.LOG_IDENTIFIERS)) {
540
+ } else if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS)) {
509
541
  // eslint-disable-next-line no-console
510
542
  console.log(`Identifiers: updated identifier ${identifier.lid} resource`, data);
511
543
  }
@@ -517,7 +549,11 @@ class IdentifierCache {
517
549
  * @private
518
550
  */
519
551
  _mergeRecordIdentifiers(keyInfo, identifier, existingIdentifier, data) {
520
- assert(`Expected keyInfo to contain an id`, hasId(keyInfo));
552
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
553
+ if (!test) {
554
+ throw new Error(`Expected keyInfo to contain an id`);
555
+ }
556
+ })(hasId(keyInfo)) : {};
521
557
  // delegate determining which identifier to keep to the configured MergeMethod
522
558
  const kept = this._merge(identifier, existingIdentifier, data);
523
559
  const abandoned = kept === identifier ? existingIdentifier : identifier;
@@ -564,7 +600,11 @@ class IdentifierCache {
564
600
  forgetRecordIdentifier(identifierObject) {
565
601
  const identifier = this.getOrCreateRecordIdentifier(identifierObject);
566
602
  const typeSet = this._cache.resourcesByType[identifier.type];
567
- assert(`Expected to find a typeSet for ${identifier.type}`, typeSet);
603
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
604
+ if (!test) {
605
+ throw new Error(`Expected to find a typeSet for ${identifier.type}`);
606
+ }
607
+ })(typeSet) : {};
568
608
  if (identifier.id !== null) {
569
609
  typeSet.id.delete(identifier.id);
570
610
  }
@@ -577,13 +617,13 @@ class IdentifierCache {
577
617
  });
578
618
  this._cache.polymorphicLidBackMap.delete(identifier.lid);
579
619
  }
580
- if (macroCondition(getOwnConfig().env.DEBUG)) {
620
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
581
621
  identifier[DEBUG_STALE_CACHE_OWNER] = identifier[CACHE_OWNER];
582
622
  }
583
623
  identifier[CACHE_OWNER] = undefined;
584
624
  IDENTIFIERS.delete(identifier);
585
625
  this._forget(identifier, 'record');
586
- if (macroCondition(getOwnConfig().debug.LOG_IDENTIFIERS)) {
626
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS)) {
587
627
  // eslint-disable-next-line no-console
588
628
  console.log(`Identifiers: released identifier ${identifierObject.lid}`);
589
629
  }
@@ -598,7 +638,7 @@ class IdentifierCache {
598
638
  }
599
639
  function makeStableRecordIdentifier(recordIdentifier, bucket, clientOriginated) {
600
640
  IDENTIFIERS.add(recordIdentifier);
601
- if (macroCondition(getOwnConfig().env.DEBUG)) {
641
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
602
642
  // we enforce immutability in dev
603
643
  // but preserve our ability to do controlled updates to the reference
604
644
  let wrapper = {
@@ -660,7 +700,7 @@ function makeStableRecordIdentifier(recordIdentifier, bucket, clientOriginated)
660
700
  return recordIdentifier;
661
701
  }
662
702
  function performRecordIdentifierUpdate(identifier, keyInfo, data, updateFn) {
663
- if (macroCondition(getOwnConfig().env.DEBUG)) {
703
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
664
704
  const {
665
705
  id,
666
706
  type
@@ -735,7 +775,7 @@ function detectMerge(cache, keyInfo, identifier, data) {
735
775
  }
736
776
  function getIdentifierFromLid(cache, lid, resource) {
737
777
  const identifier = cache.resources.get(lid);
738
- if (macroCondition(getOwnConfig().debug.LOG_IDENTIFIERS)) {
778
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_IDENTIFIERS)) {
739
779
  // eslint-disable-next-line no-console
740
780
  console.log(`Identifiers: cache ${identifier ? 'HIT' : 'MISS'} - Non-Stable ${lid}`, resource);
741
781
  }
@@ -761,10 +801,6 @@ function addResourceToCache(cache, identifier) {
761
801
  @module @ember-data/store
762
802
  */
763
803
 
764
- /**
765
- @module @ember-data/store
766
- */
767
-
768
804
  /**
769
805
  A `RecordReference` is a low-level API that allows users and
770
806
  addon authors to perform meta-operations on a record.
@@ -773,10 +809,10 @@ function addResourceToCache(cache, identifier) {
773
809
  @public
774
810
  */
775
811
  class RecordReference {
812
+ // unsubscribe token given to us by the notification manager
813
+ ___token;
814
+ ___identifier;
776
815
  constructor(store, identifier) {
777
- // unsubscribe token given to us by the notification manager
778
- this.___token = void 0;
779
- this.___identifier = void 0;
780
816
  this.store = store;
781
817
  this.___identifier = identifier;
782
818
  this.___token = store.notifications.subscribe(identifier, (_, bucket, notifiedKey) => {
@@ -919,7 +955,11 @@ class RecordReference {
919
955
  if (id !== null) {
920
956
  return this.store.findRecord(this.type, id);
921
957
  }
922
- assert(`Unable to fetch record of type ${this.type} without an id`);
958
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
959
+ {
960
+ throw new Error(`Unable to fetch record of type ${this.type} without an id`);
961
+ }
962
+ })() : {};
923
963
  }
924
964
 
925
965
  /**
@@ -942,7 +982,11 @@ class RecordReference {
942
982
  reload: true
943
983
  });
944
984
  }
945
- assert(`Unable to fetch record of type ${this.type} without an id`);
985
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
986
+ {
987
+ throw new Error(`Unable to fetch record of type ${this.type} without an id`);
988
+ }
989
+ })() : {};
946
990
  }
947
991
  }
948
992
  defineSignal(RecordReference.prototype, '_ref');
@@ -950,7 +994,6 @@ defineSignal(RecordReference.prototype, '_ref');
950
994
  /**
951
995
  @module @ember-data/store
952
996
  */
953
-
954
997
  class CacheCapabilitiesManager {
955
998
  constructor(_store) {
956
999
  this._store = _store;
@@ -995,7 +1038,11 @@ class CacheCapabilitiesManager {
995
1038
  });
996
1039
  }
997
1040
  notifyChange(identifier, namespace, key) {
998
- assert(`Expected a stable identifier`, isStableIdentifier(identifier) || isDocumentIdentifier(identifier));
1041
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1042
+ if (!test) {
1043
+ throw new Error(`Expected a stable identifier`);
1044
+ }
1045
+ })(isStableIdentifier(identifier) || isDocumentIdentifier(identifier)) : {};
999
1046
 
1000
1047
  // TODO do we still get value from this?
1001
1048
  if (namespace === 'relationships' && key) {
@@ -1006,34 +1053,49 @@ class CacheCapabilitiesManager {
1006
1053
  // @ts-expect-error
1007
1054
  this._store.notifications.notify(identifier, namespace, key);
1008
1055
  }
1009
- getSchemaDefinitionService() {
1010
- return this._store.getSchemaDefinitionService();
1011
- }
1012
1056
  get schema() {
1013
1057
  return this._store.schema;
1014
1058
  }
1015
1059
  setRecordId(identifier, id) {
1016
- assert(`Expected a stable identifier`, isStableIdentifier(identifier));
1060
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1061
+ if (!test) {
1062
+ throw new Error(`Expected a stable identifier`);
1063
+ }
1064
+ })(isStableIdentifier(identifier)) : {};
1017
1065
  this._store._instanceCache.setRecordId(identifier, id);
1018
1066
  }
1019
1067
  hasRecord(identifier) {
1020
1068
  return Boolean(this._store._instanceCache.peek(identifier));
1021
1069
  }
1022
1070
  disconnectRecord(identifier) {
1023
- assert(`Expected a stable identifier`, isStableIdentifier(identifier));
1071
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1072
+ if (!test) {
1073
+ throw new Error(`Expected a stable identifier`);
1074
+ }
1075
+ })(isStableIdentifier(identifier)) : {};
1024
1076
  this._store._instanceCache.disconnect(identifier);
1025
1077
  this._pendingNotifies.delete(identifier);
1026
1078
  }
1027
1079
  }
1080
+ if (macroCondition(getGlobalConfig().WarpDrive.deprecations.ENABLE_LEGACY_SCHEMA_SERVICE)) {
1081
+ CacheCapabilitiesManager.prototype.getSchemaDefinitionService = function () {
1082
+ // FIXME add deprecation for this
1083
+ return this._store.schema;
1084
+ };
1085
+ }
1028
1086
 
1029
1087
  /*
1030
1088
  * Returns the Cache instance associated with a given
1031
1089
  * Model or Identifier
1032
1090
  */
1033
1091
 
1034
- const CacheForIdentifierCache = new Map();
1092
+ const CacheForIdentifierCache = getOrSetGlobal('CacheForIdentifierCache', new Map());
1035
1093
  function setCacheFor(identifier, cache) {
1036
- assert(`Illegal set of identifier`, !CacheForIdentifierCache.has(identifier) || CacheForIdentifierCache.get(identifier) === cache);
1094
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1095
+ if (!test) {
1096
+ throw new Error(`Illegal set of identifier`);
1097
+ }
1098
+ })(!CacheForIdentifierCache.has(identifier) || CacheForIdentifierCache.get(identifier) === cache) : {};
1037
1099
  CacheForIdentifierCache.set(identifier, cache);
1038
1100
  }
1039
1101
  function removeRecordDataFor(identifier) {
@@ -1053,7 +1115,7 @@ function isDestroyable(record) {
1053
1115
  @module @ember-data/store
1054
1116
  */
1055
1117
 
1056
- const RecordCache = new Map();
1118
+ const RecordCache = getOrSetGlobal('RecordCache', new Map());
1057
1119
  function peekRecordIdentifier(record) {
1058
1120
  return RecordCache.get(record);
1059
1121
  }
@@ -1077,12 +1139,17 @@ function peekRecordIdentifier(record) {
1077
1139
  @param {Object} record a record instance previously obstained from the store.
1078
1140
  @return {StableRecordIdentifier}
1079
1141
  */
1142
+
1080
1143
  function recordIdentifierFor(record) {
1081
- assert(`${String(record)} is not a record instantiated by @ember-data/store`, RecordCache.has(record));
1144
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1145
+ if (!test) {
1146
+ throw new Error(`${String(record)} is not a record instantiated by @ember-data/store`);
1147
+ }
1148
+ })(RecordCache.has(record)) : {};
1082
1149
  return RecordCache.get(record);
1083
1150
  }
1084
1151
  function setRecordIdentifier(record, identifier) {
1085
- if (macroCondition(getOwnConfig().env.DEBUG)) {
1152
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
1086
1153
  if (RecordCache.has(record) && RecordCache.get(record) !== identifier) {
1087
1154
  throw new Error(`${String(record)} was already assigned an identifier`);
1088
1155
  }
@@ -1098,18 +1165,22 @@ function setRecordIdentifier(record, identifier) {
1098
1165
 
1099
1166
  RecordCache.set(record, identifier);
1100
1167
  }
1101
- const StoreMap = new Map();
1168
+ const StoreMap = getOrSetGlobal('StoreMap', new Map());
1102
1169
  function storeFor(record) {
1103
1170
  const store = StoreMap.get(record);
1104
- assert(`A record in a disconnected state cannot utilize the store. This typically means the record has been destroyed, most commonly by unloading it.`, store);
1171
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1172
+ if (!test) {
1173
+ throw new Error(`A record in a disconnected state cannot utilize the store. This typically means the record has been destroyed, most commonly by unloading it.`);
1174
+ }
1175
+ })(store) : {};
1105
1176
  return store;
1106
1177
  }
1107
1178
  class InstanceCache {
1179
+ __instances = {
1180
+ record: new Map(),
1181
+ reference: new WeakMap()
1182
+ };
1108
1183
  constructor(store) {
1109
- this.__instances = {
1110
- record: new Map(),
1111
- reference: new WeakMap()
1112
- };
1113
1184
  this.store = store;
1114
1185
  this._storeWrapper = new CacheCapabilitiesManager(this.store);
1115
1186
  store.identifierCache.__configureMerge((identifier, matchedIdentifier, resourceData) => {
@@ -1139,7 +1210,11 @@ class InstanceCache {
1139
1210
  if ('id' in resourceData) {
1140
1211
  throw new Error(`Failed to update the 'id' for the RecordIdentifier '${identifier.type}:${String(identifier.id)} (${identifier.lid})' to '${String(resourceData.id)}', because that id is already in use by '${matchedIdentifier.type}:${String(matchedIdentifier.id)} (${matchedIdentifier.lid})'`);
1141
1212
  }
1142
- assert(`Failed to update the RecordIdentifier '${identifier.type}:${String(identifier.id)} (${identifier.lid})' to merge with the detected duplicate identifier '${matchedIdentifier.type}:${String(matchedIdentifier.id)} (${String(matchedIdentifier.lid)})'`);
1213
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1214
+ {
1215
+ throw new Error(`Failed to update the RecordIdentifier '${identifier.type}:${String(identifier.id)} (${identifier.lid})' to merge with the detected duplicate identifier '${matchedIdentifier.type}:${String(matchedIdentifier.id)} (${String(matchedIdentifier.lid)})'`);
1216
+ }
1217
+ })() : {};
1143
1218
  }
1144
1219
  this.store.cache.patch({
1145
1220
  op: 'mergeIdentifiers',
@@ -1164,7 +1239,11 @@ class InstanceCache {
1164
1239
  getRecord(identifier, properties) {
1165
1240
  let record = this.__instances.record.get(identifier);
1166
1241
  if (!record) {
1167
- assert(`Cannot create a new record instance while the store is being destroyed`, !this.store.isDestroying && !this.store.isDestroyed);
1242
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1243
+ if (!test) {
1244
+ throw new Error(`Cannot create a new record instance while the store is being destroyed`);
1245
+ }
1246
+ })(!this.store.isDestroying && !this.store.isDestroyed) : {};
1168
1247
  const cache = this.store.cache;
1169
1248
  setCacheFor(identifier, cache);
1170
1249
  record = this.store.instantiateRecord(identifier, properties || {});
@@ -1172,7 +1251,7 @@ class InstanceCache {
1172
1251
  setCacheFor(record, cache);
1173
1252
  StoreMap.set(record, this.store);
1174
1253
  this.__instances.record.set(identifier, record);
1175
- if (macroCondition(getOwnConfig().debug.LOG_INSTANCE_CACHE)) {
1254
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE)) {
1176
1255
  // eslint-disable-next-line no-console
1177
1256
  console.log(`InstanceCache: created Record for ${String(identifier)}`, properties);
1178
1257
  }
@@ -1211,26 +1290,34 @@ class InstanceCache {
1211
1290
  }
1212
1291
  disconnect(identifier) {
1213
1292
  const record = this.__instances.record.get(identifier);
1214
- assert('Cannot destroy record while it is still materialized', !isDestroyable(record) || record.isDestroyed || record.isDestroying);
1293
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1294
+ if (!test) {
1295
+ throw new Error('Cannot destroy record while it is still materialized');
1296
+ }
1297
+ })(!isDestroyable(record) || record.isDestroyed || record.isDestroying) : {};
1215
1298
  this.store._graph?.remove(identifier);
1216
1299
  this.store.identifierCache.forgetRecordIdentifier(identifier);
1217
1300
  removeRecordDataFor(identifier);
1218
1301
  this.store._requestCache._clearEntries(identifier);
1219
- if (macroCondition(getOwnConfig().debug.LOG_INSTANCE_CACHE)) {
1302
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE)) {
1220
1303
  // eslint-disable-next-line no-console
1221
1304
  console.log(`InstanceCache: disconnected ${String(identifier)}`);
1222
1305
  }
1223
1306
  }
1224
1307
  unloadRecord(identifier) {
1225
- if (macroCondition(getOwnConfig().env.DEBUG)) {
1308
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
1226
1309
  const requests = this.store.getRequestStateService().getPendingRequestsForRecord(identifier);
1227
1310
  if (requests.some(req => {
1228
1311
  return req.type === 'mutation';
1229
1312
  })) {
1230
- assert(`You can only unload a record which is not inFlight. '${String(identifier)}'`);
1313
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1314
+ {
1315
+ throw new Error(`You can only unload a record which is not inFlight. '${String(identifier)}'`);
1316
+ }
1317
+ })() : {};
1231
1318
  }
1232
1319
  }
1233
- if (macroCondition(getOwnConfig().debug.LOG_INSTANCE_CACHE)) {
1320
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE)) {
1234
1321
  // eslint-disable-next-line no-console
1235
1322
  console.groupCollapsed(`InstanceCache: unloading record for ${String(identifier)}`);
1236
1323
  }
@@ -1245,7 +1332,7 @@ class InstanceCache {
1245
1332
  StoreMap.delete(record);
1246
1333
  RecordCache.delete(record);
1247
1334
  removeRecordDataFor(record);
1248
- if (macroCondition(getOwnConfig().debug.LOG_INSTANCE_CACHE)) {
1335
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE)) {
1249
1336
  // eslint-disable-next-line no-console
1250
1337
  console.log(`InstanceCache: destroyed record for ${String(identifier)}`);
1251
1338
  }
@@ -1253,7 +1340,7 @@ class InstanceCache {
1253
1340
  if (cache) {
1254
1341
  cache.unloadRecord(identifier);
1255
1342
  removeRecordDataFor(identifier);
1256
- if (macroCondition(getOwnConfig().debug.LOG_INSTANCE_CACHE)) {
1343
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE)) {
1257
1344
  // eslint-disable-next-line no-console
1258
1345
  console.log(`InstanceCache: destroyed cache for ${String(identifier)}`);
1259
1346
  }
@@ -1261,7 +1348,7 @@ class InstanceCache {
1261
1348
  this.disconnect(identifier);
1262
1349
  }
1263
1350
  this.store._requestCache._clearEntries(identifier);
1264
- if (macroCondition(getOwnConfig().debug.LOG_INSTANCE_CACHE)) {
1351
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE)) {
1265
1352
  // eslint-disable-next-line no-console
1266
1353
  console.log(`InstanceCache: unloaded RecordData for ${String(identifier)}`);
1267
1354
  // eslint-disable-next-line no-console
@@ -1300,11 +1387,19 @@ class InstanceCache {
1300
1387
  const oldId = identifier.id;
1301
1388
 
1302
1389
  // ID absolutely can't be missing if the oldID is empty (missing Id in response for a new record)
1303
- assert(`'${type}' was saved to the server, but the response does not have an id and your record does not either.`, !(id === null && oldId === null));
1390
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1391
+ if (!test) {
1392
+ throw new Error(`'${type}' was saved to the server, but the response does not have an id and your record does not either.`);
1393
+ }
1394
+ })(!(id === null && oldId === null)) : {};
1304
1395
 
1305
1396
  // ID absolutely can't be different than oldID if oldID is not null
1306
1397
  // TODO this assertion and restriction may not strictly be needed in the identifiers world
1307
- assert(`Cannot update the id for '${type}:${lid}' from '${String(oldId)}' to '${id}'.`, !(oldId !== null && id !== oldId));
1398
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1399
+ if (!test) {
1400
+ throw new Error(`Cannot update the id for '${type}:${lid}' from '${String(oldId)}' to '${id}'.`);
1401
+ }
1402
+ })(!(oldId !== null && id !== oldId)) : {};
1308
1403
 
1309
1404
  // ID can be null if oldID is not null (altered ID in response for a record)
1310
1405
  // however, this is more than likely a developer error.
@@ -1312,7 +1407,7 @@ class InstanceCache {
1312
1407
  warn(`Your ${type} record was saved to the server, but the response does not have an id.`, !(oldId !== null && id === null));
1313
1408
  return;
1314
1409
  }
1315
- if (macroCondition(getOwnConfig().debug.LOG_INSTANCE_CACHE)) {
1410
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_INSTANCE_CACHE)) {
1316
1411
  // eslint-disable-next-line no-console
1317
1412
  console.log(`InstanceCache: updating id to '${id}' for record ${String(identifier)}`);
1318
1413
  }
@@ -1320,7 +1415,11 @@ class InstanceCache {
1320
1415
  type,
1321
1416
  id
1322
1417
  });
1323
- assert(`'${type}' was saved to the server, but the response returned the new id '${id}', which has already been used with another record.'`, !existingIdentifier || existingIdentifier === identifier);
1418
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1419
+ if (!test) {
1420
+ throw new Error(`'${type}' was saved to the server, but the response returned the new id '${id}', which has already been used with another record.'`);
1421
+ }
1422
+ })(!existingIdentifier || existingIdentifier === identifier) : {};
1324
1423
  if (identifier.id === null) {
1325
1424
  // TODO potentially this needs to handle merged result
1326
1425
  this.store.identifierCache.updateRecordIdentifier(identifier, {
@@ -1357,16 +1456,16 @@ function resourceIsFullyDeleted(instanceCache, identifier) {
1357
1456
  function preloadData(store, identifier, preload) {
1358
1457
  const jsonPayload = {};
1359
1458
  //TODO(Igor) consider the polymorphic case
1360
- const schemas = store.getSchemaDefinitionService();
1361
- const relationships = schemas.relationshipsDefinitionFor(identifier);
1459
+ const schemas = store.schema;
1460
+ const fields = schemas.fields(identifier);
1362
1461
  Object.keys(preload).forEach(key => {
1363
1462
  const preloadValue = preload[key];
1364
- const relationshipMeta = relationships[key];
1365
- if (relationshipMeta) {
1463
+ const field = fields.get(key);
1464
+ if (field && (field.kind === 'hasMany' || field.kind === 'belongsTo')) {
1366
1465
  if (!jsonPayload.relationships) {
1367
1466
  jsonPayload.relationships = {};
1368
1467
  }
1369
- jsonPayload.relationships[key] = preloadRelationship(relationshipMeta, preloadValue);
1468
+ jsonPayload.relationships[key] = preloadRelationship(field, preloadValue);
1370
1469
  } else {
1371
1470
  if (!jsonPayload.attributes) {
1372
1471
  jsonPayload.attributes = {};
@@ -1381,12 +1480,20 @@ function preloadData(store, identifier, preload) {
1381
1480
  function preloadRelationship(schema, preloadValue) {
1382
1481
  const relatedType = schema.type;
1383
1482
  if (schema.kind === 'hasMany') {
1384
- assert('You need to pass in an array to set a hasMany property on a record', Array.isArray(preloadValue));
1483
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1484
+ if (!test) {
1485
+ throw new Error('You need to pass in an array to set a hasMany property on a record');
1486
+ }
1487
+ })(Array.isArray(preloadValue)) : {};
1385
1488
  return {
1386
1489
  data: preloadValue.map(value => _convertPreloadRelationshipToJSON(value, relatedType))
1387
1490
  };
1388
1491
  }
1389
- assert('You should not pass in an array to set a belongsTo property on a record', !Array.isArray(preloadValue));
1492
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1493
+ if (!test) {
1494
+ throw new Error('You should not pass in an array to set a belongsTo property on a record');
1495
+ }
1496
+ })(!Array.isArray(preloadValue)) : {};
1390
1497
  return {
1391
1498
  data: preloadValue ? _convertPreloadRelationshipToJSON(preloadValue, relatedType) : null
1392
1499
  };
@@ -1415,7 +1522,7 @@ function _clearCaches() {
1415
1522
 
1416
1523
  // if modelFor turns out to be a bottleneck we should replace with a Map
1417
1524
  // and clear it during store teardown.
1418
- const AvailableShims = new WeakMap();
1525
+ const AvailableShims = getOrSetGlobal('AvailableShims', new WeakMap());
1419
1526
  function getShimClass(store, modelName) {
1420
1527
  let shims = AvailableShims.get(store);
1421
1528
  if (!shims) {
@@ -1428,15 +1535,6 @@ function getShimClass(store, modelName) {
1428
1535
  }
1429
1536
  return shim;
1430
1537
  }
1431
- function mapFromHash(hash) {
1432
- const map = new Map();
1433
- for (const i in hash) {
1434
- if (Object.prototype.hasOwnProperty.call(hash, i)) {
1435
- map.set(i, hash[i]);
1436
- }
1437
- }
1438
- return map;
1439
- }
1440
1538
 
1441
1539
  // Mimics the static apis of @ember-data/model
1442
1540
  class ShimModelClass {
@@ -1445,67 +1543,71 @@ class ShimModelClass {
1445
1543
  this.modelName = modelName;
1446
1544
  }
1447
1545
  get fields() {
1448
- const attrs = this.__store.getSchemaDefinitionService().attributesDefinitionFor({
1546
+ const fields = new Map();
1547
+ const fieldSchemas = this.__store.schema.fields({
1449
1548
  type: this.modelName
1450
1549
  });
1451
- const relationships = this.__store.getSchemaDefinitionService().relationshipsDefinitionFor({
1452
- type: this.modelName
1550
+ fieldSchemas.forEach((schema, key) => {
1551
+ if (schema.kind === 'attribute' || schema.kind === 'belongsTo' || schema.kind === 'hasMany') {
1552
+ fields.set(key, schema.kind);
1553
+ }
1453
1554
  });
1454
- const fields = new Map();
1455
- Object.keys(attrs).forEach(key => fields.set(key, 'attribute'));
1456
- Object.keys(relationships).forEach(key => fields.set(key, relationships[key].kind));
1457
1555
  return fields;
1458
1556
  }
1459
1557
  get attributes() {
1460
- const attrs = this.__store.getSchemaDefinitionService().attributesDefinitionFor({
1558
+ const attrs = new Map();
1559
+ const fields = this.__store.schema.fields({
1461
1560
  type: this.modelName
1462
1561
  });
1463
- return mapFromHash(attrs);
1562
+ fields.forEach((schema, key) => {
1563
+ if (schema.kind === 'attribute') {
1564
+ attrs.set(key, schema);
1565
+ }
1566
+ });
1567
+ return attrs;
1464
1568
  }
1465
1569
  get relationshipsByName() {
1466
- const relationships = this.__store.getSchemaDefinitionService().relationshipsDefinitionFor({
1570
+ const rels = new Map();
1571
+ const fields = this.__store.schema.fields({
1467
1572
  type: this.modelName
1468
1573
  });
1469
- return mapFromHash(relationships);
1574
+ fields.forEach((schema, key) => {
1575
+ if (schema.kind === 'belongsTo' || schema.kind === 'hasMany') {
1576
+ rels.set(key, schema);
1577
+ }
1578
+ });
1579
+ return rels;
1470
1580
  }
1471
1581
  eachAttribute(callback, binding) {
1472
- const attrDefs = this.__store.getSchemaDefinitionService().attributesDefinitionFor({
1582
+ this.__store.schema.fields({
1473
1583
  type: this.modelName
1474
- });
1475
- Object.keys(attrDefs).forEach(key => {
1476
- callback.call(binding, key, attrDefs[key]);
1584
+ }).forEach((schema, key) => {
1585
+ if (schema.kind === 'attribute') {
1586
+ callback.call(binding, key, schema);
1587
+ }
1477
1588
  });
1478
1589
  }
1479
1590
  eachRelationship(callback, binding) {
1480
- const relationshipDefs = this.__store.getSchemaDefinitionService().relationshipsDefinitionFor({
1591
+ this.__store.schema.fields({
1481
1592
  type: this.modelName
1482
- });
1483
- Object.keys(relationshipDefs).forEach(key => {
1484
- callback.call(binding, key, relationshipDefs[key]);
1593
+ }).forEach((schema, key) => {
1594
+ if (schema.kind === 'belongsTo' || schema.kind === 'hasMany') {
1595
+ callback.call(binding, key, schema);
1596
+ }
1485
1597
  });
1486
1598
  }
1487
1599
  eachTransformedAttribute(callback, binding) {
1488
- const attrDefs = this.__store.getSchemaDefinitionService().attributesDefinitionFor({
1600
+ this.__store.schema.fields({
1489
1601
  type: this.modelName
1490
- });
1491
- Object.keys(attrDefs).forEach(key => {
1492
- if (attrDefs[key].type) {
1493
- callback.call(binding, key, attrDefs[key].type);
1602
+ }).forEach((schema, key) => {
1603
+ if (schema.kind === 'attribute') {
1604
+ const type = schema.type;
1605
+ if (type) callback.call(binding, key, type);
1494
1606
  }
1495
1607
  });
1496
1608
  }
1497
1609
  }
1498
- function _classPrivateFieldBase(receiver, privateKey) {
1499
- if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
1500
- throw new TypeError("attempted to use private field on non-instance");
1501
- }
1502
- return receiver;
1503
- }
1504
- var id = 0;
1505
- function _classPrivateFieldKey(name) {
1506
- return "__private_" + id++ + "_" + name;
1507
- }
1508
- var _cache = /*#__PURE__*/_classPrivateFieldKey("cache");
1610
+
1509
1611
  /**
1510
1612
  * The CacheManager wraps a Cache enforcing that only
1511
1613
  * the public API surface area is exposed.
@@ -1525,13 +1627,10 @@ var _cache = /*#__PURE__*/_classPrivateFieldKey("cache");
1525
1627
  * @public
1526
1628
  */
1527
1629
  class CacheManager {
1630
+ version = '2';
1631
+ #cache;
1528
1632
  constructor(cache) {
1529
- this.version = '2';
1530
- Object.defineProperty(this, _cache, {
1531
- writable: true,
1532
- value: void 0
1533
- });
1534
- _classPrivateFieldBase(this, _cache)[_cache] = cache;
1633
+ this.#cache = cache;
1535
1634
  }
1536
1635
 
1537
1636
  // Cache Management
@@ -1561,7 +1660,7 @@ class CacheManager {
1561
1660
  * @public
1562
1661
  */
1563
1662
  put(doc) {
1564
- return _classPrivateFieldBase(this, _cache)[_cache].put(doc);
1663
+ return this.#cache.put(doc);
1565
1664
  }
1566
1665
 
1567
1666
  /**
@@ -1576,7 +1675,7 @@ class CacheManager {
1576
1675
  * @return {void}
1577
1676
  */
1578
1677
  patch(op) {
1579
- _classPrivateFieldBase(this, _cache)[_cache].patch(op);
1678
+ this.#cache.patch(op);
1580
1679
  }
1581
1680
 
1582
1681
  /**
@@ -1588,7 +1687,7 @@ class CacheManager {
1588
1687
  * @param mutation
1589
1688
  */
1590
1689
  mutate(mutation) {
1591
- _classPrivateFieldBase(this, _cache)[_cache].mutate(mutation);
1690
+ this.#cache.mutate(mutation);
1592
1691
  }
1593
1692
 
1594
1693
  /**
@@ -1625,7 +1724,7 @@ class CacheManager {
1625
1724
  */
1626
1725
 
1627
1726
  peek(identifier) {
1628
- return _classPrivateFieldBase(this, _cache)[_cache].peek(identifier);
1727
+ return this.#cache.peek(identifier);
1629
1728
  }
1630
1729
 
1631
1730
  /**
@@ -1638,7 +1737,7 @@ class CacheManager {
1638
1737
  * @public
1639
1738
  */
1640
1739
  peekRequest(identifier) {
1641
- return _classPrivateFieldBase(this, _cache)[_cache].peekRequest(identifier);
1740
+ return this.#cache.peekRequest(identifier);
1642
1741
  }
1643
1742
 
1644
1743
  /**
@@ -1652,7 +1751,7 @@ class CacheManager {
1652
1751
  * @return {void | string[]} if `hasRecord` is true then calculated key changes should be returned
1653
1752
  */
1654
1753
  upsert(identifier, data, hasRecord) {
1655
- return _classPrivateFieldBase(this, _cache)[_cache].upsert(identifier, data, hasRecord);
1754
+ return this.#cache.upsert(identifier, data, hasRecord);
1656
1755
  }
1657
1756
 
1658
1757
  // Cache Forking Support
@@ -1670,7 +1769,7 @@ class CacheManager {
1670
1769
  * @return Promise<Cache>
1671
1770
  */
1672
1771
  fork() {
1673
- return _classPrivateFieldBase(this, _cache)[_cache].fork();
1772
+ return this.#cache.fork();
1674
1773
  }
1675
1774
 
1676
1775
  /**
@@ -1686,7 +1785,7 @@ class CacheManager {
1686
1785
  * @return Promise<void>
1687
1786
  */
1688
1787
  merge(cache) {
1689
- return _classPrivateFieldBase(this, _cache)[_cache].merge(cache);
1788
+ return this.#cache.merge(cache);
1690
1789
  }
1691
1790
 
1692
1791
  /**
@@ -1723,7 +1822,7 @@ class CacheManager {
1723
1822
  * @public
1724
1823
  */
1725
1824
  diff() {
1726
- return _classPrivateFieldBase(this, _cache)[_cache].diff();
1825
+ return this.#cache.diff();
1727
1826
  }
1728
1827
 
1729
1828
  // SSR Support
@@ -1739,7 +1838,7 @@ class CacheManager {
1739
1838
  * @public
1740
1839
  */
1741
1840
  dump() {
1742
- return _classPrivateFieldBase(this, _cache)[_cache].dump();
1841
+ return this.#cache.dump();
1743
1842
  }
1744
1843
 
1745
1844
  /**
@@ -1760,7 +1859,7 @@ class CacheManager {
1760
1859
  * @public
1761
1860
  */
1762
1861
  hydrate(stream) {
1763
- return _classPrivateFieldBase(this, _cache)[_cache].hydrate(stream);
1862
+ return this.#cache.hydrate(stream);
1764
1863
  }
1765
1864
 
1766
1865
  // Cache
@@ -1781,7 +1880,7 @@ class CacheManager {
1781
1880
  * @param options
1782
1881
  */
1783
1882
  clientDidCreate(identifier, options) {
1784
- return _classPrivateFieldBase(this, _cache)[_cache].clientDidCreate(identifier, options);
1883
+ return this.#cache.clientDidCreate(identifier, options);
1785
1884
  }
1786
1885
 
1787
1886
  /**
@@ -1793,7 +1892,7 @@ class CacheManager {
1793
1892
  * @param identifier
1794
1893
  */
1795
1894
  willCommit(identifier, context) {
1796
- _classPrivateFieldBase(this, _cache)[_cache].willCommit(identifier, context);
1895
+ this.#cache.willCommit(identifier, context);
1797
1896
  }
1798
1897
 
1799
1898
  /**
@@ -1806,7 +1905,7 @@ class CacheManager {
1806
1905
  * @param data
1807
1906
  */
1808
1907
  didCommit(identifier, result) {
1809
- return _classPrivateFieldBase(this, _cache)[_cache].didCommit(identifier, result);
1908
+ return this.#cache.didCommit(identifier, result);
1810
1909
  }
1811
1910
 
1812
1911
  /**
@@ -1819,7 +1918,7 @@ class CacheManager {
1819
1918
  * @param errors
1820
1919
  */
1821
1920
  commitWasRejected(identifier, errors) {
1822
- _classPrivateFieldBase(this, _cache)[_cache].commitWasRejected(identifier, errors);
1921
+ this.#cache.commitWasRejected(identifier, errors);
1823
1922
  }
1824
1923
 
1825
1924
  /**
@@ -1831,7 +1930,7 @@ class CacheManager {
1831
1930
  * @param identifier
1832
1931
  */
1833
1932
  unloadRecord(identifier) {
1834
- _classPrivateFieldBase(this, _cache)[_cache].unloadRecord(identifier);
1933
+ this.#cache.unloadRecord(identifier);
1835
1934
  }
1836
1935
 
1837
1936
  // Granular Resource Data APIs
@@ -1847,7 +1946,7 @@ class CacheManager {
1847
1946
  * @return {unknown}
1848
1947
  */
1849
1948
  getAttr(identifier, propertyName) {
1850
- return _classPrivateFieldBase(this, _cache)[_cache].getAttr(identifier, propertyName);
1949
+ return this.#cache.getAttr(identifier, propertyName);
1851
1950
  }
1852
1951
 
1853
1952
  /**
@@ -1860,7 +1959,7 @@ class CacheManager {
1860
1959
  * @param value
1861
1960
  */
1862
1961
  setAttr(identifier, propertyName, value) {
1863
- _classPrivateFieldBase(this, _cache)[_cache].setAttr(identifier, propertyName, value);
1962
+ this.#cache.setAttr(identifier, propertyName, value);
1864
1963
  }
1865
1964
 
1866
1965
  /**
@@ -1872,7 +1971,7 @@ class CacheManager {
1872
1971
  * @return
1873
1972
  */
1874
1973
  changedAttrs(identifier) {
1875
- return _classPrivateFieldBase(this, _cache)[_cache].changedAttrs(identifier);
1974
+ return this.#cache.changedAttrs(identifier);
1876
1975
  }
1877
1976
 
1878
1977
  /**
@@ -1884,7 +1983,7 @@ class CacheManager {
1884
1983
  * @return {boolean}
1885
1984
  */
1886
1985
  hasChangedAttrs(identifier) {
1887
- return _classPrivateFieldBase(this, _cache)[_cache].hasChangedAttrs(identifier);
1986
+ return this.#cache.hasChangedAttrs(identifier);
1888
1987
  }
1889
1988
 
1890
1989
  /**
@@ -1896,7 +1995,7 @@ class CacheManager {
1896
1995
  * @return the names of attributes that were restored
1897
1996
  */
1898
1997
  rollbackAttrs(identifier) {
1899
- return _classPrivateFieldBase(this, _cache)[_cache].rollbackAttrs(identifier);
1998
+ return this.#cache.rollbackAttrs(identifier);
1900
1999
  }
1901
2000
 
1902
2001
  // Relationships
@@ -1930,7 +2029,7 @@ class CacheManager {
1930
2029
  * @return {Map<string, RelationshipDiff>}
1931
2030
  */
1932
2031
  changedRelationships(identifier) {
1933
- return _classPrivateFieldBase(this, _cache)[_cache].changedRelationships(identifier);
2032
+ return this.#cache.changedRelationships(identifier);
1934
2033
  }
1935
2034
 
1936
2035
  /**
@@ -1942,7 +2041,7 @@ class CacheManager {
1942
2041
  * @return {boolean}
1943
2042
  */
1944
2043
  hasChangedRelationships(identifier) {
1945
- return _classPrivateFieldBase(this, _cache)[_cache].hasChangedRelationships(identifier);
2044
+ return this.#cache.hasChangedRelationships(identifier);
1946
2045
  }
1947
2046
 
1948
2047
  /**
@@ -1958,7 +2057,7 @@ class CacheManager {
1958
2057
  * @return {string[]} the names of relationships that were restored
1959
2058
  */
1960
2059
  rollbackRelationships(identifier) {
1961
- return _classPrivateFieldBase(this, _cache)[_cache].rollbackRelationships(identifier);
2060
+ return this.#cache.rollbackRelationships(identifier);
1962
2061
  }
1963
2062
 
1964
2063
  /**
@@ -1971,7 +2070,7 @@ class CacheManager {
1971
2070
  * @return resource relationship object
1972
2071
  */
1973
2072
  getRelationship(identifier, propertyName) {
1974
- return _classPrivateFieldBase(this, _cache)[_cache].getRelationship(identifier, propertyName);
2073
+ return this.#cache.getRelationship(identifier, propertyName);
1975
2074
  }
1976
2075
 
1977
2076
  // Resource State
@@ -1987,7 +2086,7 @@ class CacheManager {
1987
2086
  * @param isDeleted
1988
2087
  */
1989
2088
  setIsDeleted(identifier, isDeleted) {
1990
- _classPrivateFieldBase(this, _cache)[_cache].setIsDeleted(identifier, isDeleted);
2089
+ this.#cache.setIsDeleted(identifier, isDeleted);
1991
2090
  }
1992
2091
 
1993
2092
  /**
@@ -1999,7 +2098,7 @@ class CacheManager {
1999
2098
  * @return
2000
2099
  */
2001
2100
  getErrors(identifier) {
2002
- return _classPrivateFieldBase(this, _cache)[_cache].getErrors(identifier);
2101
+ return this.#cache.getErrors(identifier);
2003
2102
  }
2004
2103
 
2005
2104
  /**
@@ -2011,7 +2110,7 @@ class CacheManager {
2011
2110
  * @return {boolean}
2012
2111
  */
2013
2112
  isEmpty(identifier) {
2014
- return _classPrivateFieldBase(this, _cache)[_cache].isEmpty(identifier);
2113
+ return this.#cache.isEmpty(identifier);
2015
2114
  }
2016
2115
 
2017
2116
  /**
@@ -2024,7 +2123,7 @@ class CacheManager {
2024
2123
  * @return {boolean}
2025
2124
  */
2026
2125
  isNew(identifier) {
2027
- return _classPrivateFieldBase(this, _cache)[_cache].isNew(identifier);
2126
+ return this.#cache.isNew(identifier);
2028
2127
  }
2029
2128
 
2030
2129
  /**
@@ -2037,7 +2136,7 @@ class CacheManager {
2037
2136
  * @return {boolean}
2038
2137
  */
2039
2138
  isDeleted(identifier) {
2040
- return _classPrivateFieldBase(this, _cache)[_cache].isDeleted(identifier);
2139
+ return this.#cache.isDeleted(identifier);
2041
2140
  }
2042
2141
 
2043
2142
  /**
@@ -2050,13 +2149,14 @@ class CacheManager {
2050
2149
  * @return {boolean}
2051
2150
  */
2052
2151
  isDeletionCommitted(identifier) {
2053
- return _classPrivateFieldBase(this, _cache)[_cache].isDeletionCommitted(identifier);
2152
+ return this.#cache.isDeletionCommitted(identifier);
2054
2153
  }
2055
2154
  }
2056
2155
 
2057
2156
  /**
2058
2157
  * @module @ember-data/store
2059
2158
  */
2159
+ // eslint-disable-next-line no-restricted-imports
2060
2160
  let tokenId = 0;
2061
2161
  const CacheOperations = new Set(['added', 'removed', 'state', 'updated']);
2062
2162
  function isCacheOperationValue(value) {
@@ -2068,7 +2168,7 @@ function runLoopIsFlushing() {
2068
2168
  }
2069
2169
  function _unsubscribe(tokens, token, cache) {
2070
2170
  const identifier = tokens.get(token);
2071
- if (macroCondition(getOwnConfig().debug.LOG_NOTIFICATIONS)) {
2171
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS)) {
2072
2172
  if (!identifier) {
2073
2173
  // eslint-disable-next-line no-console
2074
2174
  console.log('Passed unknown unsubscribe token to unsubscribe', identifier);
@@ -2130,13 +2230,17 @@ class NotificationManager {
2130
2230
  */
2131
2231
 
2132
2232
  subscribe(identifier, callback) {
2133
- assert(`Expected to receive a stable Identifier to subscribe to`, identifier === 'resource' || identifier === 'document' || isStableIdentifier(identifier) || isDocumentIdentifier(identifier));
2233
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2234
+ if (!test) {
2235
+ throw new Error(`Expected to receive a stable Identifier to subscribe to`);
2236
+ }
2237
+ })(identifier === 'resource' || identifier === 'document' || isStableIdentifier(identifier) || isDocumentIdentifier(identifier)) : {};
2134
2238
  let map = this._cache.get(identifier);
2135
2239
  if (!map) {
2136
2240
  map = new Map();
2137
2241
  this._cache.set(identifier, map);
2138
2242
  }
2139
- const unsubToken = macroCondition(getOwnConfig().env.DEBUG) ? {
2243
+ const unsubToken = macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? {
2140
2244
  _tokenRef: tokenId++
2141
2245
  } : {};
2142
2246
  map.set(unsubToken, callback);
@@ -2169,15 +2273,19 @@ class NotificationManager {
2169
2273
  */
2170
2274
 
2171
2275
  notify(identifier, value, key) {
2172
- assert(`Notify does not accept a key argument for the namespace '${value}'. Received key '${key || ''}'.`, !key || value === 'attributes' || value === 'relationships');
2276
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2277
+ if (!test) {
2278
+ throw new Error(`Notify does not accept a key argument for the namespace '${value}'. Received key '${key || ''}'.`);
2279
+ }
2280
+ })(!key || value === 'attributes' || value === 'relationships') : {};
2173
2281
  if (!isStableIdentifier(identifier) && !isDocumentIdentifier(identifier)) {
2174
- if (macroCondition(getOwnConfig().debug.LOG_NOTIFICATIONS)) {
2282
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS)) {
2175
2283
  // eslint-disable-next-line no-console
2176
2284
  console.log(`Notifying: Expected to receive a stable Identifier to notify '${value}' '${key || ''}' with, but ${String(identifier)} is not in the cache`, identifier);
2177
2285
  }
2178
2286
  return false;
2179
2287
  }
2180
- if (macroCondition(getOwnConfig().debug.LOG_NOTIFICATIONS)) {
2288
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS)) {
2181
2289
  // eslint-disable-next-line no-console
2182
2290
  console.log(`Buffering Notify: ${String(identifier.lid)}\t${value}\t${key || ''}`);
2183
2291
  }
@@ -2224,7 +2332,7 @@ class NotificationManager {
2224
2332
  this._onFlushCB = undefined;
2225
2333
  }
2226
2334
  _flushNotification(identifier, value, key) {
2227
- if (macroCondition(getOwnConfig().debug.LOG_NOTIFICATIONS)) {
2335
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS)) {
2228
2336
  // eslint-disable-next-line no-console
2229
2337
  console.log(`Notifying: ${String(identifier)}\t${value}\t${key || ''}`);
2230
2338
  }
@@ -2254,30 +2362,139 @@ class NotificationManager {
2254
2362
  this._cache.clear();
2255
2363
  }
2256
2364
  }
2257
- function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
2258
- var desc = {};
2259
- Object.keys(descriptor).forEach(function (key) {
2260
- desc[key] = descriptor[key];
2365
+
2366
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2367
+ /*
2368
+ We redefine Proxy because the native Proxy type treats the `target` and
2369
+ `receiver` as the same type incorrectly.
2370
+
2371
+ We ported this from Typescript's own Proxy types on 3/10/2024.
2372
+ */
2373
+
2374
+ const NativeProxy = Proxy;
2375
+ var __defProp = Object.defineProperty;
2376
+ var __export = (target, all) => {
2377
+ for (var name in all) __defProp(target, name, {
2378
+ get: all[name],
2379
+ enumerable: true
2261
2380
  });
2262
- desc.enumerable = !!desc.enumerable;
2263
- desc.configurable = !!desc.configurable;
2264
- if ('value' in desc || desc.initializer) {
2265
- desc.writable = true;
2266
- }
2267
- desc = decorators.slice().reverse().reduce(function (desc, decorator) {
2268
- return decorator(target, property, desc) || desc;
2269
- }, desc);
2270
- if (context && desc.initializer !== void 0) {
2271
- desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
2272
- desc.initializer = undefined;
2381
+ };
2382
+
2383
+ // src/runtime.ts
2384
+ var runtime_exports = {};
2385
+ __export(runtime_exports, {
2386
+ c: () => decorateClass,
2387
+ f: () => decorateFieldV1,
2388
+ g: () => decorateFieldV2,
2389
+ i: () => initializeDeferredDecorator,
2390
+ m: () => decorateMethodV1,
2391
+ n: () => decorateMethodV2,
2392
+ p: () => decoratePOJO
2393
+ });
2394
+ var deferred = /* @__PURE__ */new WeakMap();
2395
+ function deferDecorator(proto, prop, desc) {
2396
+ let map = deferred.get(proto);
2397
+ if (!map) {
2398
+ map = /* @__PURE__ */new Map();
2399
+ deferred.set(proto, map);
2400
+ }
2401
+ map.set(prop, desc);
2402
+ }
2403
+ function findDeferredDecorator(target, prop) {
2404
+ let cursor = target.prototype;
2405
+ while (cursor) {
2406
+ let desc = deferred.get(cursor)?.get(prop);
2407
+ if (desc) {
2408
+ return desc;
2409
+ }
2410
+ cursor = cursor.prototype;
2411
+ }
2412
+ }
2413
+ function decorateFieldV1(target, prop, decorators, initializer) {
2414
+ return decorateFieldV2(target.prototype, prop, decorators, initializer);
2415
+ }
2416
+ function decorateFieldV2(prototype, prop, decorators, initializer) {
2417
+ let desc = {
2418
+ configurable: true,
2419
+ enumerable: true,
2420
+ writable: true,
2421
+ initializer: null
2422
+ };
2423
+ if (initializer) {
2424
+ desc.initializer = initializer;
2425
+ }
2426
+ for (let decorator of decorators) {
2427
+ desc = decorator(prototype, prop, desc) || desc;
2273
2428
  }
2274
2429
  if (desc.initializer === void 0) {
2275
- Object.defineProperty(target, property, desc);
2276
- desc = null;
2430
+ Object.defineProperty(prototype, prop, desc);
2431
+ } else {
2432
+ deferDecorator(prototype, prop, desc);
2277
2433
  }
2278
- return desc;
2279
2434
  }
2280
- var _class;
2435
+ function decorateMethodV1({
2436
+ prototype
2437
+ }, prop, decorators) {
2438
+ return decorateMethodV2(prototype, prop, decorators);
2439
+ }
2440
+ function decorateMethodV2(prototype, prop, decorators) {
2441
+ const origDesc = Object.getOwnPropertyDescriptor(prototype, prop);
2442
+ let desc = {
2443
+ ...origDesc
2444
+ };
2445
+ for (let decorator of decorators) {
2446
+ desc = decorator(prototype, prop, desc) || desc;
2447
+ }
2448
+ if (desc.initializer !== void 0) {
2449
+ desc.value = desc.initializer ? desc.initializer.call(prototype) : void 0;
2450
+ desc.initializer = void 0;
2451
+ }
2452
+ Object.defineProperty(prototype, prop, desc);
2453
+ }
2454
+ function initializeDeferredDecorator(target, prop) {
2455
+ let desc = findDeferredDecorator(target.constructor, prop);
2456
+ if (desc) {
2457
+ Object.defineProperty(target, prop, {
2458
+ enumerable: desc.enumerable,
2459
+ configurable: desc.configurable,
2460
+ writable: desc.writable,
2461
+ value: desc.initializer ? desc.initializer.call(target) : void 0
2462
+ });
2463
+ }
2464
+ }
2465
+ function decorateClass(target, decorators) {
2466
+ return decorators.reduce((accum, decorator) => decorator(accum) || accum, target);
2467
+ }
2468
+ function decoratePOJO(pojo, decorated) {
2469
+ for (let [type, prop, decorators] of decorated) {
2470
+ if (type === "field") {
2471
+ decoratePojoField(pojo, prop, decorators);
2472
+ } else {
2473
+ decorateMethodV2(pojo, prop, decorators);
2474
+ }
2475
+ }
2476
+ return pojo;
2477
+ }
2478
+ function decoratePojoField(pojo, prop, decorators) {
2479
+ let desc = {
2480
+ configurable: true,
2481
+ enumerable: true,
2482
+ writable: true,
2483
+ initializer: () => Object.getOwnPropertyDescriptor(pojo, prop)?.value
2484
+ };
2485
+ for (let decorator of decorators) {
2486
+ desc = decorator(pojo, prop, desc) || desc;
2487
+ }
2488
+ if (desc.initializer) {
2489
+ desc.value = desc.initializer.call(pojo);
2490
+ delete desc.initializer;
2491
+ }
2492
+ Object.defineProperty(pojo, prop, desc);
2493
+ }
2494
+
2495
+ /**
2496
+ @module @ember-data/store
2497
+ */
2281
2498
  const ARRAY_GETTER_METHODS = new Set([Symbol.iterator, 'concat', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'flat', 'flatMap', 'forEach', 'includes', 'indexOf', 'join', 'keys', 'lastIndexOf', 'map', 'reduce', 'reduceRight', 'slice', 'some', 'values']);
2282
2499
  const ARRAY_SETTER_METHODS = new Set(['push', 'pop', 'unshift', 'shift', 'splice', 'sort']);
2283
2500
  const SYNC_PROPS = new Set(['[]', 'length', 'links', 'meta']);
@@ -2290,11 +2507,11 @@ function isArraySetter(prop) {
2290
2507
  function isSelfProp(self, prop) {
2291
2508
  return prop in self;
2292
2509
  }
2293
- const ARRAY_SIGNAL = Symbol('#signal');
2294
- const SOURCE = Symbol('#source');
2295
- const MUTATE = Symbol('#update');
2296
- const NOTIFY = Symbol('#notify');
2297
- const IS_COLLECTION = Symbol.for('Collection');
2510
+ const ARRAY_SIGNAL = getOrSetGlobal('#signal', Symbol('#signal'));
2511
+ const SOURCE = getOrSetGlobal('#source', Symbol('#source'));
2512
+ const MUTATE = getOrSetGlobal('#update', Symbol('#update'));
2513
+ const NOTIFY = getOrSetGlobal('#notify', Symbol('#notify'));
2514
+ const IS_COLLECTION = getOrSetGlobal('IS_COLLECTION', Symbol.for('Collection'));
2298
2515
  function notifyArray(arr) {
2299
2516
  addToTransaction(arr[ARRAY_SIGNAL]);
2300
2517
  }
@@ -2310,7 +2527,11 @@ function safeForEach(instance, arr, store, callback, target) {
2310
2527
  }
2311
2528
  // clone to prevent mutation
2312
2529
  arr = arr.slice();
2313
- assert('`forEach` expects a function as first argument.', typeof callback === 'function');
2530
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2531
+ if (!test) {
2532
+ throw new Error('`forEach` expects a function as first argument.');
2533
+ }
2534
+ })(typeof callback === 'function') : {};
2314
2535
 
2315
2536
  // because we retrieveLatest above we need not worry if array is mutated during iteration
2316
2537
  // by unloadRecord/rollbackAttributes
@@ -2336,7 +2557,28 @@ function safeForEach(instance, arr, store, callback, target) {
2336
2557
  @class RecordArray
2337
2558
  @public
2338
2559
  */
2339
- let IdentifierArray = (_class = class IdentifierArray {
2560
+
2561
+ class IdentifierArray {
2562
+ /**
2563
+ The flag to signal a `RecordArray` is currently loading data.
2564
+ Example
2565
+ ```javascript
2566
+ let people = store.peekAll('person');
2567
+ people.isUpdating; // false
2568
+ people.update();
2569
+ people.isUpdating; // true
2570
+ ```
2571
+ @property isUpdating
2572
+ @public
2573
+ @type Boolean
2574
+ */
2575
+
2576
+ isLoaded = true;
2577
+ isDestroying = false;
2578
+ isDestroyed = false;
2579
+ _updatingPromise = null;
2580
+ [IS_COLLECTION] = true;
2581
+ [SOURCE];
2340
2582
  [NOTIFY]() {
2341
2583
  notifyArray(this);
2342
2584
  }
@@ -2361,29 +2603,13 @@ let IdentifierArray = (_class = class IdentifierArray {
2361
2603
  get length() {
2362
2604
  return this[SOURCE].length;
2363
2605
  }
2606
+ static {
2607
+ decorateMethodV2(this.prototype, "length", [compat]);
2608
+ }
2364
2609
  set length(value) {
2365
2610
  this[SOURCE].length = value;
2366
2611
  }
2367
2612
  constructor(options) {
2368
- /**
2369
- The flag to signal a `RecordArray` is currently loading data.
2370
- Example
2371
- ```javascript
2372
- let people = store.peekAll('person');
2373
- people.isUpdating; // false
2374
- people.update();
2375
- people.isUpdating; // true
2376
- ```
2377
- @property isUpdating
2378
- @public
2379
- @type Boolean
2380
- */
2381
- this.isLoaded = true;
2382
- this.isDestroying = false;
2383
- this.isDestroyed = false;
2384
- this._updatingPromise = null;
2385
- this[IS_COLLECTION] = true;
2386
- this[SOURCE] = void 0;
2387
2613
  // eslint-disable-next-line @typescript-eslint/no-this-alias
2388
2614
  const self = this;
2389
2615
  this.modelName = options.type;
@@ -2404,7 +2630,7 @@ let IdentifierArray = (_class = class IdentifierArray {
2404
2630
  // we track all mutations within the call
2405
2631
  // and forward them as one
2406
2632
 
2407
- const proxy = new Proxy(this[SOURCE], {
2633
+ const proxy = new NativeProxy(this[SOURCE], {
2408
2634
  get(target, prop, receiver) {
2409
2635
  const index = convertToInt(prop);
2410
2636
  if (_SIGNAL.shouldReset && (index !== null || SYNC_PROPS.has(prop) || isArrayGetter(prop))) {
@@ -2455,11 +2681,19 @@ let IdentifierArray = (_class = class IdentifierArray {
2455
2681
  // array functions must run through Reflect to work properly
2456
2682
  // binding via other means will not work.
2457
2683
  if (!options.allowMutation) {
2458
- assert(`Mutating this array of records via ${String(prop)} is not allowed.`, options.allowMutation);
2684
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2685
+ if (!test) {
2686
+ throw new Error(`Mutating this array of records via ${String(prop)} is not allowed.`);
2687
+ }
2688
+ })(options.allowMutation) : {};
2459
2689
  return;
2460
2690
  }
2461
2691
  const args = Array.prototype.slice.call(arguments);
2462
- assert(`Cannot start a new array transaction while a previous transaction is underway`, !transaction);
2692
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2693
+ if (!test) {
2694
+ throw new Error(`Cannot start a new array transaction while a previous transaction is underway`);
2695
+ }
2696
+ })(!transaction) : {};
2463
2697
  transaction = true;
2464
2698
  const result = self[MUTATE](target, receiver, prop, args, _SIGNAL);
2465
2699
  transaction = false;
@@ -2501,7 +2735,11 @@ let IdentifierArray = (_class = class IdentifierArray {
2501
2735
  } else if (transaction) {
2502
2736
  return Reflect.set(target, prop, value);
2503
2737
  } else {
2504
- assert(`unexpected length set`);
2738
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2739
+ {
2740
+ throw new Error(`unexpected length set`);
2741
+ }
2742
+ })() : {};
2505
2743
  }
2506
2744
  }
2507
2745
  if (prop === 'links') {
@@ -2524,23 +2762,36 @@ let IdentifierArray = (_class = class IdentifierArray {
2524
2762
  if (index === null || index > target.length) {
2525
2763
  if (index !== null && transaction) {
2526
2764
  const identifier = recordIdentifierFor(value);
2527
- assert(`Cannot set index ${index} past the end of the array.`, isStableIdentifier(identifier));
2765
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2766
+ if (!test) {
2767
+ throw new Error(`Cannot set index ${index} past the end of the array.`);
2768
+ }
2769
+ })(isStableIdentifier(identifier)) : {};
2528
2770
  target[index] = identifier;
2529
2771
  return true;
2530
2772
  } else if (isSelfProp(self, prop)) {
2773
+ // @ts-expect-error not all properties are indeces and we can't safely cast
2531
2774
  self[prop] = value;
2532
2775
  return true;
2533
2776
  }
2534
2777
  return false;
2535
2778
  }
2536
2779
  if (!options.allowMutation) {
2537
- assert(`Mutating ${String(prop)} on this RecordArray is not allowed.`, options.allowMutation);
2780
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2781
+ if (!test) {
2782
+ throw new Error(`Mutating ${String(prop)} on this Array is not allowed.`);
2783
+ }
2784
+ })(options.allowMutation) : {};
2538
2785
  return false;
2539
2786
  }
2540
2787
  const original = target[index];
2541
2788
  const newIdentifier = extractIdentifierFromRecord$1(value);
2542
2789
  target[index] = newIdentifier;
2543
- assert(`Expected a record`, isStableIdentifier(newIdentifier));
2790
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2791
+ if (!test) {
2792
+ throw new Error(`Expected a record`);
2793
+ }
2794
+ })(isStableIdentifier(newIdentifier)) : {};
2544
2795
  // We generate "transactions" whenever a setter method on the array
2545
2796
  // is called and might bulk update multiple array cells. Fundamentally,
2546
2797
  // all array operations decompose into individual cell replacements.
@@ -2565,7 +2816,11 @@ let IdentifierArray = (_class = class IdentifierArray {
2565
2816
  return true;
2566
2817
  },
2567
2818
  deleteProperty(target, prop) {
2568
- assert(`Deleting keys on managed arrays is disallowed`, transaction);
2819
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2820
+ if (!test) {
2821
+ throw new Error(`Deleting keys on managed arrays is disallowed`);
2822
+ }
2823
+ })(transaction) : {};
2569
2824
  if (!transaction) {
2570
2825
  return false;
2571
2826
  }
@@ -2613,11 +2868,19 @@ let IdentifierArray = (_class = class IdentifierArray {
2613
2868
  }
2614
2869
 
2615
2870
  /*
2616
- Update this RecordArray and return a promise which resolves once the update
2871
+ Update this Array and return a promise which resolves once the update
2617
2872
  is finished.
2618
2873
  */
2619
2874
  _update() {
2620
- assert(`_update cannot be used with this array`, this.modelName);
2875
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2876
+ if (!test) {
2877
+ throw new Error(`_update cannot be used with this array`);
2878
+ }
2879
+ })(this.modelName) : {};
2880
+ // @ts-expect-error typescript is unable to handle the complexity of
2881
+ // T = unknown, modelName = string
2882
+ // T extends TypedRecordInstance, modelName = TypeFromInstance<T>
2883
+ // both being valid options to pass through here.
2621
2884
  return this.store.findAll(this.modelName, {
2622
2885
  reload: true
2623
2886
  });
@@ -2642,7 +2905,9 @@ let IdentifierArray = (_class = class IdentifierArray {
2642
2905
  const promise = Promise.all(this.map(record => this.store.saveRecord(record))).then(() => this);
2643
2906
  return promise;
2644
2907
  }
2645
- }, _applyDecoratedDescriptor(_class.prototype, "length", [compat], Object.getOwnPropertyDescriptor(_class.prototype, "length"), _class.prototype), _class); // this will error if someone tries to call
2908
+ }
2909
+
2910
+ // this will error if someone tries to call
2646
2911
  // A(identifierArray) since it is not configurable
2647
2912
  // which is preferable to the `meta` override we used
2648
2913
  // before which required importing all of Ember
@@ -2657,9 +2922,9 @@ compat(desc);
2657
2922
  Object.defineProperty(IdentifierArray.prototype, '[]', desc);
2658
2923
  defineSignal(IdentifierArray.prototype, 'isUpdating', false);
2659
2924
  class Collection extends IdentifierArray {
2925
+ query = null;
2660
2926
  constructor(options) {
2661
2927
  super(options);
2662
- this.query = null;
2663
2928
  this.query = options.query || null;
2664
2929
  this.isLoaded = options.isLoaded || false;
2665
2930
  }
@@ -2670,8 +2935,20 @@ class Collection extends IdentifierArray {
2670
2935
  } = this;
2671
2936
 
2672
2937
  // TODO save options from initial request?
2673
- assert(`update cannot be used with this array`, this.modelName);
2674
- assert(`update cannot be used with no query`, query);
2938
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2939
+ if (!test) {
2940
+ throw new Error(`update cannot be used with this array`);
2941
+ }
2942
+ })(this.modelName) : {};
2943
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2944
+ if (!test) {
2945
+ throw new Error(`update cannot be used with no query`);
2946
+ }
2947
+ })(query) : {};
2948
+ // @ts-expect-error typescript is unable to handle the complexity of
2949
+ // T = unknown, modelName = string
2950
+ // T extends TypedRecordInstance, modelName = TypeFromInstance<T>
2951
+ // both being valid options to pass through here.
2675
2952
  const promise = store.query(this.modelName, query, {
2676
2953
  _recordArray: this
2677
2954
  });
@@ -2690,14 +2967,18 @@ Collection.prototype.query = null;
2690
2967
  // Object.setPrototypeOf(IdentifierArray.prototype, Array.prototype);
2691
2968
 
2692
2969
  function assertRecordPassedToHasMany(record) {
2693
- assert(`All elements of a hasMany relationship must be instances of Model, you passed $${typeof record}`, function () {
2970
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2971
+ if (!test) {
2972
+ throw new Error(`All elements of a hasMany relationship must be instances of Model, you passed $${typeof record}`);
2973
+ }
2974
+ })(function () {
2694
2975
  try {
2695
2976
  recordIdentifierFor(record);
2696
2977
  return true;
2697
2978
  } catch {
2698
2979
  return false;
2699
2980
  }
2700
- }());
2981
+ }()) : {};
2701
2982
  }
2702
2983
  function extractIdentifierFromRecord$1(record) {
2703
2984
  if (!record) {
@@ -2710,7 +2991,7 @@ function extractIdentifierFromRecord$1(record) {
2710
2991
  /**
2711
2992
  @module @ember-data/store
2712
2993
  */
2713
- const FAKE_ARR = {};
2994
+ const FAKE_ARR = getOrSetGlobal('FAKE_ARR', {});
2714
2995
  const SLICE_BATCH_SIZE = 1200;
2715
2996
  /**
2716
2997
  * This is a clever optimization.
@@ -3058,9 +3339,10 @@ function sync(array, changes, arraySet) {
3058
3339
  /**
3059
3340
  * @module @ember-data/store
3060
3341
  */
3061
- const Touching = Symbol('touching');
3062
- const RequestPromise = Symbol('promise');
3063
- const EMPTY_ARR = macroCondition(getOwnConfig().env.DEBUG) ? Object.freeze([]) : [];
3342
+
3343
+ const Touching = getOrSetGlobal('Touching', Symbol('touching'));
3344
+ const RequestPromise = getOrSetGlobal('RequestPromise', Symbol('promise'));
3345
+ const EMPTY_ARR = macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? Object.freeze([]) : [];
3064
3346
  function hasRecordIdentifier(op) {
3065
3347
  return 'recordIdentifier' in op;
3066
3348
  }
@@ -3073,12 +3355,12 @@ function hasRecordIdentifier(op) {
3073
3355
  * @public
3074
3356
  */
3075
3357
  class RequestStateService {
3358
+ _pending = new Map();
3359
+ _done = new Map();
3360
+ _subscriptions = new Map();
3361
+ _toFlush = [];
3362
+ _store;
3076
3363
  constructor(store) {
3077
- this._pending = new Map();
3078
- this._done = new Map();
3079
- this._subscriptions = new Map();
3080
- this._toFlush = [];
3081
- this._store = void 0;
3082
3364
  this._store = store;
3083
3365
  }
3084
3366
  _clearEntries(identifier) {
@@ -3131,7 +3413,11 @@ class RequestStateService {
3131
3413
  throw error;
3132
3414
  });
3133
3415
  }
3134
- assert(`Expected a well formed query`);
3416
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
3417
+ {
3418
+ throw new Error(`Expected a well formed query`);
3419
+ }
3420
+ })() : {};
3135
3421
  }
3136
3422
  _triggerSubscriptions(req) {
3137
3423
  if (req.state === 'pending') {
@@ -3264,8 +3550,16 @@ function constructResource(type, id, lid) {
3264
3550
  if ('id' in resource) {
3265
3551
  resource.id = coerceId(resource.id);
3266
3552
  }
3267
- assert('Expected either id or lid to be a valid string', 'id' in resource && isNonEmptyString(resource.id) || isNonEmptyString(resource.lid));
3268
- assert('if id is present, the type must be a string', !('id' in resource) || typeof resource.type === 'string');
3553
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
3554
+ if (!test) {
3555
+ throw new Error('Expected either id or lid to be a valid string');
3556
+ }
3557
+ })('id' in resource && isNonEmptyString(resource.id) || isNonEmptyString(resource.lid)) : {};
3558
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
3559
+ if (!test) {
3560
+ throw new Error('if id is present, the type must be a string');
3561
+ }
3562
+ })(!('id' in resource) || typeof resource.type === 'string') : {};
3269
3563
  return resource;
3270
3564
  } else {
3271
3565
  const trueId = coerceId(id);
@@ -3277,7 +3571,11 @@ function constructResource(type, id, lid) {
3277
3571
  }
3278
3572
  throw new Error('Expected either id or lid to be a valid string');
3279
3573
  }
3280
- assert('type must be a string', typeof type === 'string');
3574
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
3575
+ if (!test) {
3576
+ throw new Error('type must be a string');
3577
+ }
3578
+ })(typeof type === 'string') : {};
3281
3579
  if (isNonEmptyString(lid)) {
3282
3580
  return {
3283
3581
  type,
@@ -3297,6 +3595,26 @@ function constructResource(type, id, lid) {
3297
3595
  */
3298
3596
  // this import location is deprecated but breaks in 4.8 and older
3299
3597
 
3598
+ // `AwaitedKeys` is needed here to resolve any promise types like `PromiseBelongsTo`.
3599
+
3600
+ /**
3601
+ * Currently only records that extend object can be created via
3602
+ * store.createRecord. This is a limitation of the current API,
3603
+ * but can be worked around by creating a new identifier, running
3604
+ * the cache.clientDidCreate method, and then peeking the record
3605
+ * for the identifier.
3606
+ *
3607
+ * To assign primary key to a record during creation, only `id` will
3608
+ * work correctly for `store.createRecord`, other primary key may be
3609
+ * handled by updating the record after creation or using the flow
3610
+ * described above.
3611
+ *
3612
+ * TODO: These are limitations we want to (and can) address. If you
3613
+ * have need of lifting these limitations, please open an issue.
3614
+ *
3615
+ * @typedoc
3616
+ */
3617
+
3300
3618
  /**
3301
3619
  * A Store coordinates interaction between your application, a [Cache](https://api.emberjs.com/ember-data/release/classes/%3CInterface%3E%20Cache),
3302
3620
  * and sources of data (such as your API or a local persistence layer)
@@ -3308,18 +3626,47 @@ function constructResource(type, id, lid) {
3308
3626
  * export default class extends Store {}
3309
3627
  * ```
3310
3628
  *
3311
- * Most Ember applications will only have a single `Store` configured as a Service
3629
+ * Most Applications will only have a single `Store` configured as a Service
3312
3630
  * in this manner. However, setting up multiple stores is possible, including using
3313
- * each as a unique service.
3631
+ * each as a unique service or within a specific context.
3314
3632
  *
3315
3633
 
3316
3634
  @class Store
3317
3635
  @public
3318
3636
  */
3319
-
3320
- // @ts-expect-error
3321
-
3322
- class Store extends EmberObject {
3637
+ // eslint-disable-next-line @typescript-eslint/no-extraneous-class
3638
+ const EmptyClass = class {
3639
+ // eslint-disable-next-line @typescript-eslint/no-useless-constructor
3640
+ constructor(args) {}
3641
+ };
3642
+ const BaseClass = macroCondition(dependencySatisfies('ember-source', '*')) ? macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_STORE_EXTENDS_EMBER_OBJECT) ? importSync('@ember/object') : EmptyClass : EmptyClass;
3643
+ if (BaseClass !== EmptyClass) {
3644
+ deprecate(`The Store class extending from EmberObject is deprecated.
3645
+ Please remove usage of EmberObject APIs and mark your class as not requiring it.
3646
+
3647
+ To mark the class as no longer extending from EmberObject, in ember-cli-build.js
3648
+ set the following config:
3649
+
3650
+ \`\`\`js
3651
+ const app = new EmberApp(defaults, {
3652
+ emberData: {
3653
+ deprecations: {
3654
+ DEPRECATE_STORE_EXTENDS_EMBER_OBJECT: false
3655
+ }
3656
+ }
3657
+ });
3658
+ \`\`\`
3659
+ `, false, {
3660
+ id: 'ember-data:deprecate-store-extends-ember-object',
3661
+ until: '6.0',
3662
+ for: 'ember-data',
3663
+ since: {
3664
+ available: '5.4',
3665
+ enabled: '5.4'
3666
+ }
3667
+ });
3668
+ }
3669
+ class Store extends BaseClass {
3323
3670
  /**
3324
3671
  * Provides access to the NotificationManager associated
3325
3672
  * with this Store instance.
@@ -3342,7 +3689,10 @@ class Store extends EmberObject {
3342
3689
  * @public
3343
3690
  */
3344
3691
  get schema() {
3345
- return this.getSchemaDefinitionService();
3692
+ if (!this._schema) {
3693
+ this._schema = this.createSchemaService();
3694
+ }
3695
+ return this._schema;
3346
3696
  }
3347
3697
 
3348
3698
  /**
@@ -3368,7 +3718,7 @@ class Store extends EmberObject {
3368
3718
  * ```ts
3369
3719
  * import Store, { CacheHandler } from '@ember-data/store';
3370
3720
  * import RequestManager from '@ember-data/request';
3371
- * import Fetch from '@ember/data/request/fetch';
3721
+ * import Fetch from '@ember-data/request/fetch';
3372
3722
  *
3373
3723
  * class extends Store {
3374
3724
  * constructor() {
@@ -3385,7 +3735,7 @@ class Store extends EmberObject {
3385
3735
  */
3386
3736
 
3387
3737
  /**
3388
- * A Property which an App may set to provide a Lifetimes Service
3738
+ * A Property which an App may set to provide a CachePolicy
3389
3739
  * to control when a cached request becomes stale.
3390
3740
  *
3391
3741
  * Note, when defined, these methods will only be invoked if a
@@ -3411,7 +3761,7 @@ class Store extends EmberObject {
3411
3761
  * ```
3412
3762
  *
3413
3763
  * @public
3414
- * @property {LivetimesService|undefined} lifetimes
3764
+ * @property {CachePolicy|undefined} lifetimes
3415
3765
  */
3416
3766
 
3417
3767
  // Private
@@ -3436,7 +3786,6 @@ class Store extends EmberObject {
3436
3786
  @private
3437
3787
  */
3438
3788
  constructor(createArgs) {
3439
- // @ts-expect-error ember-source types improperly expect createArgs to be `Owner`
3440
3789
  super(createArgs);
3441
3790
  Object.assign(this, createArgs);
3442
3791
  this.identifierCache = new IdentifierCache();
@@ -3455,9 +3804,13 @@ class Store extends EmberObject {
3455
3804
  this.isDestroyed = false;
3456
3805
  }
3457
3806
  _run(cb) {
3458
- assert(`EmberData should never encounter a nested run`, !this._cbs);
3807
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
3808
+ if (!test) {
3809
+ throw new Error(`EmberData should never encounter a nested run`);
3810
+ }
3811
+ })(!this._cbs) : {};
3459
3812
  const _cbs = this._cbs = {};
3460
- if (macroCondition(getOwnConfig().env.DEBUG)) {
3813
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
3461
3814
  try {
3462
3815
  cb();
3463
3816
  if (_cbs.coalesce) {
@@ -3494,8 +3847,16 @@ class Store extends EmberObject {
3494
3847
  }
3495
3848
  }
3496
3849
  _schedule(name, cb) {
3497
- assert(`EmberData expects to schedule only when there is an active run`, !!this._cbs);
3498
- assert(`EmberData expects only one flush per queue name, cannot schedule ${name}`, !this._cbs[name]);
3850
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
3851
+ if (!test) {
3852
+ throw new Error(`EmberData expects to schedule only when there is an active run`);
3853
+ }
3854
+ })(!!this._cbs) : {};
3855
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
3856
+ if (!test) {
3857
+ throw new Error(`EmberData expects only one flush per queue name, cannot schedule ${name}`);
3858
+ }
3859
+ })(!this._cbs[name]) : {};
3499
3860
  this._cbs[name] = cb;
3500
3861
  }
3501
3862
 
@@ -3514,7 +3875,7 @@ class Store extends EmberObject {
3514
3875
  return this._requestCache;
3515
3876
  }
3516
3877
  _getAllPending() {
3517
- if (macroCondition(getOwnConfig().env.TESTING)) {
3878
+ if (macroCondition(getGlobalConfig().WarpDrive.env.TESTING)) {
3518
3879
  const all = [];
3519
3880
  const pending = this._requestCache._pending;
3520
3881
  pending.forEach(requests => {
@@ -3539,7 +3900,7 @@ class Store extends EmberObject {
3539
3900
  * and document cached.
3540
3901
  *
3541
3902
  * The cache key used is `requestConfig.cacheOptions.key`
3542
- * if present, falling back to `requestconfig.url`.
3903
+ * if present, falling back to `requestConfig.url`.
3543
3904
  *
3544
3905
  * Params are not serialized as part of the cache-key, so
3545
3906
  * either ensure they are already in the url or utilize
@@ -3557,7 +3918,7 @@ class Store extends EmberObject {
3557
3918
  * When a cache-key is determined, the request may fulfill
3558
3919
  * from cache provided the cache is not stale.
3559
3920
  *
3560
- * Cache staleness is determined by the configured LifetimesService
3921
+ * Cache staleness is determined by the configured CachePolicy
3561
3922
  * with priority given to the `cacheOptions.reload` and
3562
3923
  * `cacheOptions.backgroundReload` on the request if present.
3563
3924
  *
@@ -3592,12 +3953,12 @@ class Store extends EmberObject {
3592
3953
  const identifierCache = this.identifierCache;
3593
3954
  opts.records = requestConfig.records.map(r => identifierCache.getOrCreateRecordIdentifier(r));
3594
3955
  }
3595
- if (macroCondition(getOwnConfig().env.TESTING)) {
3956
+ if (macroCondition(getGlobalConfig().WarpDrive.env.TESTING)) {
3596
3957
  if (this.DISABLE_WAITER) {
3597
3958
  opts.disableTestWaiter = typeof requestConfig.disableTestWaiter === 'boolean' ? requestConfig.disableTestWaiter : true;
3598
3959
  }
3599
3960
  }
3600
- if (macroCondition(getOwnConfig().debug.LOG_REQUESTS)) {
3961
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_REQUESTS)) {
3601
3962
  let options;
3602
3963
  try {
3603
3964
  options = JSON.parse(JSON.stringify(requestConfig));
@@ -3607,9 +3968,10 @@ class Store extends EmberObject {
3607
3968
  // eslint-disable-next-line no-console
3608
3969
  console.log(`request: [[START]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`, options);
3609
3970
  }
3610
- const future = this.requestManager.request(Object.assign(requestConfig, opts));
3971
+ const request = Object.assign({}, requestConfig, opts);
3972
+ const future = this.requestManager.request(request);
3611
3973
  future.onFinalize(() => {
3612
- if (macroCondition(getOwnConfig().debug.LOG_REQUESTS)) {
3974
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_REQUESTS)) {
3613
3975
  // eslint-disable-next-line no-console
3614
3976
  console.log(`request: [[FINALIZE]] ${requestConfig.op && !requestConfig.url ? '(LEGACY) ' : ''}${requestConfig.op || '<unknown operation>'} ${requestConfig.url || '<empty url>'} ${requestConfig.method || '<empty method>'}`);
3615
3977
  }
@@ -3628,7 +3990,7 @@ class Store extends EmberObject {
3628
3990
  * a resource.
3629
3991
  *
3630
3992
  * This hook can be used to select or instantiate any desired
3631
- * mechanism of presentating cache data to the ui for access
3993
+ * mechanism of presenting cache data to the ui for access
3632
3994
  * mutation, and interaction.
3633
3995
  *
3634
3996
  * @method instantiateRecord (hook)
@@ -3652,134 +4014,7 @@ class Store extends EmberObject {
3652
4014
  */
3653
4015
 
3654
4016
  /**
3655
- * Provides access to the SchemaDefinitionService instance
3656
- * for this Store instance.
3657
- *
3658
- * The SchemaDefinitionService can be used to query for
3659
- * information about the schema of a resource.
3660
- *
3661
- * @method getSchemaDefinitionService
3662
- * @public
3663
- */
3664
- getSchemaDefinitionService() {
3665
- assert(`You must registerSchemaDefinitionService with the store to use custom model classes`, this._schema);
3666
- return this._schema;
3667
- }
3668
-
3669
- /**
3670
- * DEPRECATED - Use `registerSchema` instead.
3671
- *
3672
- * Allows an app to register a custom SchemaService
3673
- * for use when information about a resource's schema needs
3674
- * to be queried.
3675
- *
3676
- * This method can only be called more than once, but only one schema
3677
- * definition service may exist. Therefore if you wish to chain services
3678
- * you must lookup the existing service and close over it with the new
3679
- * service by accessing `store.schema` prior to registration.
3680
- *
3681
- * For Example:
3682
- *
3683
- * ```ts
3684
- * import Store from '@ember-data/store';
3685
- *
3686
- * class SchemaDelegator {
3687
- * constructor(schema) {
3688
- * this._schema = schema;
3689
- * }
3690
- *
3691
- * doesTypeExist(type: string): boolean {
3692
- * if (AbstractSchemas.has(type)) {
3693
- * return true;
3694
- * }
3695
- * return this._schema.doesTypeExist(type);
3696
- * }
3697
- *
3698
- * attributesDefinitionFor(identifier: RecordIdentifier | { type: string }): AttributesSchema {
3699
- * return this._schema.attributesDefinitionFor(identifier);
3700
- * }
3701
- *
3702
- * relationshipsDefinitionFor(identifier: RecordIdentifier | { type: string }): RelationshipsSchema {
3703
- * const schema = AbstractSchemas.get(identifier.type);
3704
- * return schema || this._schema.relationshipsDefinitionFor(identifier);
3705
- * }
3706
- * }
3707
- *
3708
- * export default class extends Store {
3709
- * constructor(...args) {
3710
- * super(...args);
3711
- *
3712
- * const schema = this.schema;
3713
- * this.registerSchemaDefinitionService(new SchemaDelegator(schema));
3714
- * }
3715
- * }
3716
- * ```
3717
- *
3718
- * @method registerSchemaDefinitionService
3719
- * @param {SchemaService} schema
3720
- * @deprecated
3721
- * @public
3722
- */
3723
- registerSchemaDefinitionService(schema) {
3724
- this._schema = schema;
3725
- }
3726
- /**
3727
- * Allows an app to register a custom SchemaService
3728
- * for use when information about a resource's schema needs
3729
- * to be queried.
3730
- *
3731
- * This method can only be called more than once, but only one schema
3732
- * definition service may exist. Therefore if you wish to chain services
3733
- * you must lookup the existing service and close over it with the new
3734
- * service by accessing `store.schema` prior to registration.
3735
- *
3736
- * For Example:
3737
- *
3738
- * ```ts
3739
- * import Store from '@ember-data/store';
3740
- *
3741
- * class SchemaDelegator {
3742
- * constructor(schema) {
3743
- * this._schema = schema;
3744
- * }
3745
- *
3746
- * doesTypeExist(type: string): boolean {
3747
- * if (AbstractSchemas.has(type)) {
3748
- * return true;
3749
- * }
3750
- * return this._schema.doesTypeExist(type);
3751
- * }
3752
- *
3753
- * attributesDefinitionFor(identifier: RecordIdentifier | { type: string }): AttributesSchema {
3754
- * return this._schema.attributesDefinitionFor(identifier);
3755
- * }
3756
- *
3757
- * relationshipsDefinitionFor(identifier: RecordIdentifier | { type: string }): RelationshipsSchema {
3758
- * const schema = AbstractSchemas.get(identifier.type);
3759
- * return schema || this._schema.relationshipsDefinitionFor(identifier);
3760
- * }
3761
- * }
3762
- *
3763
- * export default class extends Store {
3764
- * constructor(...args) {
3765
- * super(...args);
3766
- *
3767
- * const schema = this.schema;
3768
- * this.registerSchema(new SchemaDelegator(schema));
3769
- * }
3770
- * }
3771
- * ```
3772
- *
3773
- * @method registerSchema
3774
- * @param {SchemaService} schema
3775
- * @public
3776
- */
3777
- registerSchema(schema) {
3778
- this._schema = schema;
3779
- }
3780
-
3781
- /**
3782
- Returns the schema for a particular `modelName`.
4017
+ Returns the schema for a particular resource type (modelName).
3783
4018
  When used with Model from @ember-data/model the return is the model class,
3784
4019
  but this is not guaranteed.
3785
4020
  If looking to query attribute or relationship information it is
@@ -3793,17 +4028,29 @@ class Store extends EmberObject {
3793
4028
  for example.
3794
4029
  @method modelFor
3795
4030
  @public
3796
- @param {String} type
4031
+ @deprecated
4032
+ @param {string} type
3797
4033
  @return {ModelSchema}
3798
4034
  */
3799
- // TODO @deprecate in favor of schema APIs, requires adapter/serializer overhaul or replacement
3800
4035
 
3801
4036
  modelFor(type) {
3802
- if (macroCondition(getOwnConfig().env.DEBUG)) {
4037
+ // FIXME add deprecation and deprecation stripping
4038
+ // FIXME/TODO update RFC to remove this method
4039
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
3803
4040
  assertDestroyedStoreOnly(this, 'modelFor');
3804
4041
  }
3805
- assert(`You need to pass <type> to the store's modelFor method`, typeof type === 'string' && type.length);
3806
- assert(`No model was found for '${type}' and no schema handles the type`, this.getSchemaDefinitionService().doesTypeExist(type));
4042
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4043
+ if (!test) {
4044
+ throw new Error(`You need to pass <type> to the store's modelFor method`);
4045
+ }
4046
+ })(typeof type === 'string' && type.length) : {};
4047
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4048
+ if (!test) {
4049
+ throw new Error(`No model was found for '${type}' and no schema handles the type`);
4050
+ }
4051
+ })(this.schema.hasResource({
4052
+ type
4053
+ })) : {};
3807
4054
  return getShimClass(this, type);
3808
4055
  }
3809
4056
 
@@ -3818,7 +4065,7 @@ class Store extends EmberObject {
3818
4065
  ```
3819
4066
  To create a new instance of a `Post` that has a relationship with a `User` record:
3820
4067
  ```js
3821
- let user = this.store.peekRecord('user', 1);
4068
+ let user = this.store.peekRecord('user', '1');
3822
4069
  store.createRecord('post', {
3823
4070
  title: 'Ember is awesome!',
3824
4071
  user: user
@@ -3826,17 +4073,26 @@ class Store extends EmberObject {
3826
4073
  ```
3827
4074
  @method createRecord
3828
4075
  @public
3829
- @param {String} modelName
4076
+ @param {String} type the name of the resource
3830
4077
  @param {Object} inputProperties a hash of properties to set on the
3831
4078
  newly created record.
3832
4079
  @return {Model} record
3833
4080
  */
3834
- createRecord(modelName, inputProperties) {
3835
- if (macroCondition(getOwnConfig().env.DEBUG)) {
4081
+
4082
+ createRecord(type, inputProperties) {
4083
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
3836
4084
  assertDestroyingStore(this, 'createRecord');
3837
4085
  }
3838
- assert(`You need to pass a model name to the store's createRecord method`, modelName);
3839
- assert(`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${modelName}`, typeof modelName === 'string');
4086
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4087
+ if (!test) {
4088
+ throw new Error(`You need to pass a model name to the store's createRecord method`);
4089
+ }
4090
+ })(type) : {};
4091
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4092
+ if (!test) {
4093
+ throw new Error(`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${type}`);
4094
+ }
4095
+ })(typeof type === 'string') : {};
3840
4096
 
3841
4097
  // This is wrapped in a `run.join` so that in test environments users do not need to manually wrap
3842
4098
  // calls to `createRecord`. The run loop usage here is because we batch the joining and updating
@@ -3845,7 +4101,7 @@ class Store extends EmberObject {
3845
4101
  // to remove this, we would need to move to a new `async` API.
3846
4102
  let record;
3847
4103
  this._join(() => {
3848
- const normalizedModelName = normalizeModelName(modelName);
4104
+ const normalizedModelName = normalizeModelName(type);
3849
4105
  const properties = {
3850
4106
  ...inputProperties
3851
4107
  };
@@ -3854,25 +4110,28 @@ class Store extends EmberObject {
3854
4110
  // give the adapter an opportunity to generate one. Typically,
3855
4111
  // client-side ID generators will use something like uuid.js
3856
4112
  // to avoid conflicts.
3857
-
4113
+ let id = null;
3858
4114
  if (properties.id === null || properties.id === undefined) {
3859
- const adapter = this.adapterFor?.(modelName, true);
4115
+ const adapter = this.adapterFor?.(normalizedModelName, true);
3860
4116
  if (adapter && adapter.generateIdForRecord) {
3861
- properties.id = adapter.generateIdForRecord(this, modelName, properties);
4117
+ id = properties.id = coerceId(adapter.generateIdForRecord(this, normalizedModelName, properties));
3862
4118
  } else {
3863
- properties.id = null;
4119
+ id = properties.id = null;
3864
4120
  }
4121
+ } else {
4122
+ id = properties.id = coerceId(properties.id);
3865
4123
  }
3866
-
3867
- // Coerce ID to a string
3868
- properties.id = coerceId(properties.id);
3869
4124
  const resource = {
3870
4125
  type: normalizedModelName,
3871
- id: properties.id
4126
+ id
3872
4127
  };
3873
4128
  if (resource.id) {
3874
4129
  const identifier = this.identifierCache.peekRecordIdentifier(resource);
3875
- assert(`The id ${String(properties.id)} has already been used with another '${normalizedModelName}' record.`, !identifier);
4130
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4131
+ if (!test) {
4132
+ throw new Error(`The id ${String(properties.id)} has already been used with another '${normalizedModelName}' record.`);
4133
+ }
4134
+ })(!identifier) : {};
3876
4135
  }
3877
4136
  const identifier = this.identifierCache.createIdentifierForNewRecord(resource);
3878
4137
  const cache = this.cache;
@@ -3894,15 +4153,19 @@ class Store extends EmberObject {
3894
4153
  ```
3895
4154
  @method deleteRecord
3896
4155
  @public
3897
- @param {Model} record
4156
+ @param {unknown} record
3898
4157
  */
3899
4158
  deleteRecord(record) {
3900
- if (macroCondition(getOwnConfig().env.DEBUG)) {
4159
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
3901
4160
  assertDestroyingStore(this, 'deleteRecord');
3902
4161
  }
3903
4162
  const identifier = peekRecordIdentifier(record);
3904
4163
  const cache = this.cache;
3905
- assert(`expected the record to be connected to a cache`, identifier);
4164
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4165
+ if (!test) {
4166
+ throw new Error(`expected the record to be connected to a cache`);
4167
+ }
4168
+ })(identifier) : {};
3906
4169
  this._join(() => {
3907
4170
  cache.setIsDeleted(identifier, true);
3908
4171
  if (cache.isNew(identifier)) {
@@ -3916,7 +4179,7 @@ class Store extends EmberObject {
3916
4179
  This will cause the record to be destroyed and freed up for garbage collection.
3917
4180
  Example
3918
4181
  ```javascript
3919
- store.findRecord('post', 1).then(function(post) {
4182
+ store.findRecord('post', '1').then(function(post) {
3920
4183
  store.unloadRecord(post);
3921
4184
  });
3922
4185
  ```
@@ -3925,7 +4188,7 @@ class Store extends EmberObject {
3925
4188
  @param {Model} record
3926
4189
  */
3927
4190
  unloadRecord(record) {
3928
- if (macroCondition(getOwnConfig().env.DEBUG)) {
4191
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
3929
4192
  assertDestroyingStore(this, 'unloadRecord');
3930
4193
  }
3931
4194
  const identifier = peekRecordIdentifier(record);
@@ -3942,8 +4205,7 @@ class Store extends EmberObject {
3942
4205
  resolved with the record.
3943
4206
  **Example 1**
3944
4207
  ```app/routes/post.js
3945
- import Route from '@ember/routing/route';
3946
- export default class PostRoute extends Route {
4208
+ export default class PostRoute extends Route {
3947
4209
  model({ post_id }) {
3948
4210
  return this.store.findRecord('post', post_id);
3949
4211
  }
@@ -3954,8 +4216,7 @@ class Store extends EmberObject {
3954
4216
  of `type` (modelName) and `id` as separate arguments. You may recognize this combo as
3955
4217
  the typical pairing from [JSON:API](https://jsonapi.org/format/#document-resource-object-identification)
3956
4218
  ```app/routes/post.js
3957
- import Route from '@ember/routing/route';
3958
- export default class PostRoute extends Route {
4219
+ export default class PostRoute extends Route {
3959
4220
  model({ post_id: id }) {
3960
4221
  return this.store.findRecord({ type: 'post', id });
3961
4222
  }
@@ -3978,8 +4239,7 @@ class Store extends EmberObject {
3978
4239
  for the comment also looks like `/posts/1/comments/2` if you want to fetch the comment
3979
4240
  without also fetching the post you can pass in the post to the `findRecord` call:
3980
4241
  ```app/routes/post-comments.js
3981
- import Route from '@ember/routing/route';
3982
- export default class PostRoute extends Route {
4242
+ export default class PostRoute extends Route {
3983
4243
  model({ post_id, comment_id: id }) {
3984
4244
  return this.store.findRecord({ type: 'comment', id, { preload: { post: post_id }} });
3985
4245
  }
@@ -4005,8 +4265,7 @@ class Store extends EmberObject {
4005
4265
  This could also be achieved by supplying the post id to the adapter via the adapterOptions
4006
4266
  property on the options hash.
4007
4267
  ```app/routes/post-comments.js
4008
- import Route from '@ember/routing/route';
4009
- export default class PostRoute extends Route {
4268
+ export default class PostRoute extends Route {
4010
4269
  model({ post_id, comment_id: id }) {
4011
4270
  return this.store.findRecord({ type: 'comment', id, { adapterOptions: { post: post_id }} });
4012
4271
  }
@@ -4029,8 +4288,8 @@ class Store extends EmberObject {
4029
4288
  ```
4030
4289
  If you have access to the post model you can also pass the model itself to preload:
4031
4290
  ```javascript
4032
- let post = await store.findRecord('post', 1);
4033
- let comment = await store.findRecord('comment', 2, { post: myPostModel });
4291
+ let post = await store.findRecord('post', '1');
4292
+ let comment = await store.findRecord('comment', '2', { post: myPostModel });
4034
4293
  ```
4035
4294
  ### Reloading
4036
4295
  The reload behavior is configured either via the passed `options` hash or
@@ -4054,7 +4313,7 @@ class Store extends EmberObject {
4054
4313
  // revision: 2
4055
4314
  // }
4056
4315
  // ]
4057
- store.findRecord('post', 1, { reload: true }).then(function(post) {
4316
+ store.findRecord('post', '1', { reload: true }).then(function(post) {
4058
4317
  post.revision; // 2
4059
4318
  });
4060
4319
  ```
@@ -4083,7 +4342,7 @@ class Store extends EmberObject {
4083
4342
  revision: 1
4084
4343
  }
4085
4344
  });
4086
- let blogPost = store.findRecord('post', 1).then(function(post) {
4345
+ let blogPost = store.findRecord('post', '1').then(function(post) {
4087
4346
  post.revision; // 1
4088
4347
  });
4089
4348
  // later, once adapter#findRecord resolved with
@@ -4100,8 +4359,7 @@ class Store extends EmberObject {
4100
4359
  boolean value for `backgroundReload` in the options object for
4101
4360
  `findRecord`.
4102
4361
  ```app/routes/post/edit.js
4103
- import Route from '@ember/routing/route';
4104
- export default class PostEditRoute extends Route {
4362
+ export default class PostEditRoute extends Route {
4105
4363
  model(params) {
4106
4364
  return this.store.findRecord('post', params.post_id, { backgroundReload: false });
4107
4365
  }
@@ -4110,8 +4368,7 @@ class Store extends EmberObject {
4110
4368
  If you pass an object on the `adapterOptions` property of the options
4111
4369
  argument it will be passed to your adapter via the snapshot
4112
4370
  ```app/routes/post/edit.js
4113
- import Route from '@ember/routing/route';
4114
- export default class PostEditRoute extends Route {
4371
+ export default class PostEditRoute extends Route {
4115
4372
  model(params) {
4116
4373
  return this.store.findRecord('post', params.post_id, {
4117
4374
  adapterOptions: { subscribe: false }
@@ -4143,8 +4400,7 @@ class Store extends EmberObject {
4143
4400
  model, when we retrieve a specific post we can have the server also return that post's
4144
4401
  comments in the same request:
4145
4402
  ```app/routes/post.js
4146
- import Route from '@ember/routing/route';
4147
- export default class PostRoute extends Route {
4403
+ export default class PostRoute extends Route {
4148
4404
  model(params) {
4149
4405
  return this.store.findRecord('post', params.post_id, { include: 'comments' });
4150
4406
  }
@@ -4172,8 +4428,7 @@ class Store extends EmberObject {
4172
4428
  using a dot-separated sequence of relationship names. So to request both the post's
4173
4429
  comments and the authors of those comments the request would look like this:
4174
4430
  ```app/routes/post.js
4175
- import Route from '@ember/routing/route';
4176
- export default class PostRoute extends Route {
4431
+ export default class PostRoute extends Route {
4177
4432
  model(params) {
4178
4433
  return this.store.findRecord('post', params.post_id, { include: 'comments,comments.author' });
4179
4434
  }
@@ -4196,41 +4451,47 @@ class Store extends EmberObject {
4196
4451
  2. Then pass through the applicable fields to your `findRecord` request.
4197
4452
  Given a `post` model with attributes body, title, publishDate and meta, you can retrieve a filtered list of attributes.
4198
4453
  ```app/routes/post.js
4199
- import Route from '@ember/routing/route';
4200
- export default Route.extend({
4454
+ export default class extends Route {
4201
4455
  model(params) {
4202
4456
  return this.store.findRecord('post', params.post_id, { adapterOptions: { fields: { post: 'body,title' } });
4203
4457
  }
4204
- });
4458
+ }
4205
4459
  ```
4206
4460
  Moreover, you can filter attributes on related models as well. If a `post` has a `belongsTo` relationship to a user,
4207
4461
  just include the relationship key and attributes.
4208
4462
  ```app/routes/post.js
4209
- import Route from '@ember/routing/route';
4210
- export default Route.extend({
4463
+ export default class extends Route {
4211
4464
  model(params) {
4212
4465
  return this.store.findRecord('post', params.post_id, { adapterOptions: { fields: { post: 'body,title', user: 'name,email' } });
4213
4466
  }
4214
- });
4467
+ }
4215
4468
  ```
4216
4469
  @since 1.13.0
4217
4470
  @method findRecord
4218
4471
  @public
4219
- @param {String|object} modelName - either a string representing the modelName or a ResourceIdentifier object containing both the type (a string) and the id (a string) for the record or an lid (a string) of an existing record
4472
+ @param {String|object} type - either a string representing the name of the resource or a ResourceIdentifier object containing both the type (a string) and the id (a string) for the record or an lid (a string) of an existing record
4220
4473
  @param {(String|Integer|Object)} id - optional object with options for the request only if the first param is a ResourceIdentifier, else the string id of the record to be retrieved
4221
4474
  @param {Object} [options] - if the first param is a string this will be the optional options for the request. See examples for available options.
4222
4475
  @return {Promise} promise
4223
4476
  */
4224
4477
 
4225
4478
  findRecord(resource, id, options) {
4226
- if (macroCondition(getOwnConfig().env.DEBUG)) {
4479
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
4227
4480
  assertDestroyingStore(this, 'findRecord');
4228
4481
  }
4229
- assert(`You need to pass a modelName or resource identifier as the first argument to the store's findRecord method`, resource);
4482
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4483
+ if (!test) {
4484
+ throw new Error(`You need to pass a modelName or resource identifier as the first argument to the store's findRecord method`);
4485
+ }
4486
+ })(resource) : {};
4230
4487
  if (isMaybeIdentifier(resource)) {
4231
4488
  options = id;
4232
4489
  } else {
4233
- assert(`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${resource}`, typeof resource === 'string');
4490
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4491
+ if (!test) {
4492
+ throw new Error(`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${resource}`);
4493
+ }
4494
+ })(typeof resource === 'string') : {};
4234
4495
  const type = normalizeModelName(resource);
4235
4496
  const normalizedId = ensureStringId(id);
4236
4497
  resource = constructResource(type, normalizedId);
@@ -4267,7 +4528,7 @@ class Store extends EmberObject {
4267
4528
  Get the reference for the specified record.
4268
4529
  Example
4269
4530
  ```javascript
4270
- let userRef = store.getReference('user', 1);
4531
+ let userRef = store.getReference('user', '1');
4271
4532
  // check if the user is loaded
4272
4533
  let isLoaded = userRef.value() !== null;
4273
4534
  // get the record of the reference (null if not yet available)
@@ -4294,7 +4555,7 @@ class Store extends EmberObject {
4294
4555
  */
4295
4556
  // TODO @deprecate getReference (and references generally)
4296
4557
  getReference(resource, id) {
4297
- if (macroCondition(getOwnConfig().env.DEBUG)) {
4558
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
4298
4559
  assertDestroyingStore(this, 'getReference');
4299
4560
  }
4300
4561
  let resourceIdentifier;
@@ -4305,7 +4566,11 @@ class Store extends EmberObject {
4305
4566
  const normalizedId = ensureStringId(id);
4306
4567
  resourceIdentifier = constructResource(type, normalizedId);
4307
4568
  }
4308
- assert('getReference expected to receive either a resource identifier or type and id as arguments', isMaybeIdentifier(resourceIdentifier));
4569
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4570
+ if (!test) {
4571
+ throw new Error('getReference expected to receive either a resource identifier or type and id as arguments');
4572
+ }
4573
+ })(isMaybeIdentifier(resourceIdentifier)) : {};
4309
4574
  const identifier = this.identifierCache.getOrCreateRecordIdentifier(resourceIdentifier);
4310
4575
  return this._instanceCache.getReference(identifier);
4311
4576
  }
@@ -4319,8 +4584,8 @@ class Store extends EmberObject {
4319
4584
  _Note: This is a synchronous method and does not return a promise._
4320
4585
  **Example 1**
4321
4586
  ```js
4322
- let post = store.peekRecord('post', 1);
4323
- post.id; // 1
4587
+ let post = store.peekRecord('post', '1');
4588
+ post.id; // '1'
4324
4589
  ```
4325
4590
  `peekRecord` can be called with a single identifier argument instead of the combination
4326
4591
  of `type` (modelName) and `id` as separate arguments. You may recognize this combo as
@@ -4328,14 +4593,14 @@ class Store extends EmberObject {
4328
4593
  **Example 2**
4329
4594
  ```js
4330
4595
  let post = store.peekRecord({ type: 'post', id });
4331
- post.id; // 1
4596
+ post.id; // '1'
4332
4597
  ```
4333
4598
  If you have previously received an lid from an Identifier for this record, you can lookup the record again using
4334
4599
  just the lid.
4335
4600
  **Example 3**
4336
4601
  ```js
4337
4602
  let post = store.peekRecord({ lid });
4338
- post.id; // 1
4603
+ post.id; // '1'
4339
4604
  ```
4340
4605
  @since 1.13.0
4341
4606
  @method peekRecord
@@ -4353,11 +4618,19 @@ class Store extends EmberObject {
4353
4618
  // this is basically an "are we not empty" query.
4354
4619
  return isLoaded ? this._instanceCache.getRecord(stableIdentifier) : null;
4355
4620
  }
4356
- if (macroCondition(getOwnConfig().env.DEBUG)) {
4621
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
4357
4622
  assertDestroyingStore(this, 'peekRecord');
4358
4623
  }
4359
- assert(`You need to pass a model name to the store's peekRecord method`, identifier);
4360
- assert(`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${String(identifier)}`, typeof identifier === 'string');
4624
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4625
+ if (!test) {
4626
+ throw new Error(`You need to pass a model name to the store's peekRecord method`);
4627
+ }
4628
+ })(identifier) : {};
4629
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4630
+ if (!test) {
4631
+ throw new Error(`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${String(identifier)}`);
4632
+ }
4633
+ })(typeof identifier === 'string') : {};
4361
4634
  const type = normalizeModelName(identifier);
4362
4635
  const normalizedId = ensureStringId(id);
4363
4636
  const resource = {
@@ -4388,7 +4661,7 @@ class Store extends EmberObject {
4388
4661
  ---
4389
4662
  If you do something like this:
4390
4663
  ```javascript
4391
- store.query('person', { ids: [1, 2, 3] });
4664
+ store.query('person', { ids: ['1', '2', '3'] });
4392
4665
  ```
4393
4666
  The request made to the server will look something like this:
4394
4667
  ```
@@ -4401,24 +4674,37 @@ class Store extends EmberObject {
4401
4674
  @since 1.13.0
4402
4675
  @method query
4403
4676
  @public
4404
- @param {String} modelName
4405
- @param {any} query an opaque query to be used by the adapter
4677
+ @param {String} type the name of the resource
4678
+ @param {object} query a query to be used by the adapter
4406
4679
  @param {Object} options optional, may include `adapterOptions` hash which will be passed to adapter.query
4407
4680
  @return {Promise} promise
4408
4681
  */
4409
- query(modelName, query, options) {
4410
- if (macroCondition(getOwnConfig().env.DEBUG)) {
4682
+
4683
+ query(type, query, options = {}) {
4684
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
4411
4685
  assertDestroyingStore(this, 'query');
4412
4686
  }
4413
- assert(`You need to pass a model name to the store's query method`, modelName);
4414
- assert(`You need to pass a query hash to the store's query method`, query);
4415
- assert(`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${modelName}`, typeof modelName === 'string');
4687
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4688
+ if (!test) {
4689
+ throw new Error(`You need to pass a model name to the store's query method`);
4690
+ }
4691
+ })(type) : {};
4692
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4693
+ if (!test) {
4694
+ throw new Error(`You need to pass a query hash to the store's query method`);
4695
+ }
4696
+ })(query) : {};
4697
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4698
+ if (!test) {
4699
+ throw new Error(`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${type}`);
4700
+ }
4701
+ })(typeof type === 'string') : {};
4416
4702
  const promise = this.request({
4417
4703
  op: 'query',
4418
4704
  data: {
4419
- type: normalizeModelName(modelName),
4705
+ type: normalizeModelName(type),
4420
4706
  query,
4421
- options: options || {}
4707
+ options: options
4422
4708
  },
4423
4709
  cacheOptions: {
4424
4710
  [SkipCache]: true
@@ -4503,22 +4789,35 @@ class Store extends EmberObject {
4503
4789
  @since 1.13.0
4504
4790
  @method queryRecord
4505
4791
  @public
4506
- @param {String} modelName
4507
- @param {any} query an opaque query to be used by the adapter
4508
- @param {Object} options optional, may include `adapterOptions` hash which will be passed to adapter.queryRecord
4792
+ @param {string} type
4793
+ @param {object} query an opaque query to be used by the adapter
4794
+ @param {object} options optional, may include `adapterOptions` hash which will be passed to adapter.queryRecord
4509
4795
  @return {Promise} promise which resolves with the found record or `null`
4510
4796
  */
4511
- queryRecord(modelName, query, options) {
4512
- if (macroCondition(getOwnConfig().env.DEBUG)) {
4797
+
4798
+ queryRecord(type, query, options) {
4799
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
4513
4800
  assertDestroyingStore(this, 'queryRecord');
4514
4801
  }
4515
- assert(`You need to pass a model name to the store's queryRecord method`, modelName);
4516
- assert(`You need to pass a query hash to the store's queryRecord method`, query);
4517
- assert(`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${modelName}`, typeof modelName === 'string');
4802
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4803
+ if (!test) {
4804
+ throw new Error(`You need to pass a model name to the store's queryRecord method`);
4805
+ }
4806
+ })(type) : {};
4807
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4808
+ if (!test) {
4809
+ throw new Error(`You need to pass a query hash to the store's queryRecord method`);
4810
+ }
4811
+ })(query) : {};
4812
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4813
+ if (!test) {
4814
+ throw new Error(`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${type}`);
4815
+ }
4816
+ })(typeof type === 'string') : {};
4518
4817
  const promise = this.request({
4519
4818
  op: 'queryRecord',
4520
4819
  data: {
4521
- type: normalizeModelName(modelName),
4820
+ type: normalizeModelName(type),
4522
4821
  query,
4523
4822
  options: options || {}
4524
4823
  },
@@ -4535,8 +4834,7 @@ class Store extends EmberObject {
4535
4834
  this type present in the store, even if the adapter only returns a subset
4536
4835
  of them.
4537
4836
  ```app/routes/authors.js
4538
- import Route from '@ember/routing/route';
4539
- export default class AuthorsRoute extends Route {
4837
+ export default class AuthorsRoute extends Route {
4540
4838
  model(params) {
4541
4839
  return this.store.findAll('author');
4542
4840
  }
@@ -4609,8 +4907,7 @@ class Store extends EmberObject {
4609
4907
  boolean value for `backgroundReload` in the options object for
4610
4908
  `findAll`.
4611
4909
  ```app/routes/post/edit.js
4612
- import Route from '@ember/routing/route';
4613
- export default class PostEditRoute extends Route {
4910
+ export default class PostEditRoute extends Route {
4614
4911
  model() {
4615
4912
  return this.store.findAll('post', { backgroundReload: false });
4616
4913
  }
@@ -4619,8 +4916,7 @@ class Store extends EmberObject {
4619
4916
  If you pass an object on the `adapterOptions` property of the options
4620
4917
  argument it will be passed to you adapter via the `snapshotRecordArray`
4621
4918
  ```app/routes/posts.js
4622
- import Route from '@ember/routing/route';
4623
- export default class PostsRoute extends Route {
4919
+ export default class PostsRoute extends Route {
4624
4920
  model(params) {
4625
4921
  return this.store.findAll('post', {
4626
4922
  adapterOptions: { subscribe: false }
@@ -4653,8 +4949,7 @@ class Store extends EmberObject {
4653
4949
  model, when we retrieve all of the post records we can have the server also return
4654
4950
  all of the posts' comments in the same request:
4655
4951
  ```app/routes/posts.js
4656
- import Route from '@ember/routing/route';
4657
- export default class PostsRoute extends Route {
4952
+ export default class PostsRoute extends Route {
4658
4953
  model() {
4659
4954
  return this.store.findAll('post', { include: 'comments' });
4660
4955
  }
@@ -4665,8 +4960,7 @@ class Store extends EmberObject {
4665
4960
  using a dot-separated sequence of relationship names. So to request both the posts'
4666
4961
  comments and the authors of those comments the request would look like this:
4667
4962
  ```app/routes/posts.js
4668
- import Route from '@ember/routing/route';
4669
- export default class PostsRoute extends Route {
4963
+ export default class PostsRoute extends Route {
4670
4964
  model() {
4671
4965
  return this.store.findAll('post', { include: 'comments,comments.author' });
4672
4966
  }
@@ -4676,20 +4970,29 @@ class Store extends EmberObject {
4676
4970
  @since 1.13.0
4677
4971
  @method findAll
4678
4972
  @public
4679
- @param {String} modelName
4680
- @param {Object} options
4973
+ @param {string} type the name of the resource
4974
+ @param {object} options
4681
4975
  @return {Promise} promise
4682
4976
  */
4683
- findAll(modelName, options = {}) {
4684
- if (macroCondition(getOwnConfig().env.DEBUG)) {
4977
+
4978
+ findAll(type, options = {}) {
4979
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
4685
4980
  assertDestroyingStore(this, 'findAll');
4686
4981
  }
4687
- assert(`You need to pass a model name to the store's findAll method`, modelName);
4688
- assert(`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${modelName}`, typeof modelName === 'string');
4982
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4983
+ if (!test) {
4984
+ throw new Error(`You need to pass a model name to the store's findAll method`);
4985
+ }
4986
+ })(type) : {};
4987
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4988
+ if (!test) {
4989
+ throw new Error(`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${type}`);
4990
+ }
4991
+ })(typeof type === 'string') : {};
4689
4992
  const promise = this.request({
4690
4993
  op: 'findAll',
4691
4994
  data: {
4692
- type: normalizeModelName(modelName),
4995
+ type: normalizeModelName(type),
4693
4996
  options: options || {}
4694
4997
  },
4695
4998
  cacheOptions: {
@@ -4716,17 +5019,25 @@ class Store extends EmberObject {
4716
5019
  @since 1.13.0
4717
5020
  @method peekAll
4718
5021
  @public
4719
- @param {String} modelName
5022
+ @param {string} type the name of the resource
4720
5023
  @return {RecordArray}
4721
5024
  */
4722
- peekAll(modelName) {
4723
- if (macroCondition(getOwnConfig().env.DEBUG)) {
5025
+
5026
+ peekAll(type) {
5027
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
4724
5028
  assertDestroyingStore(this, 'peekAll');
4725
5029
  }
4726
- assert(`You need to pass a model name to the store's peekAll method`, modelName);
4727
- assert(`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${modelName}`, typeof modelName === 'string');
4728
- const type = normalizeModelName(modelName);
4729
- return this.recordArrayManager.liveArrayFor(type);
5030
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5031
+ if (!test) {
5032
+ throw new Error(`You need to pass a model name to the store's peekAll method`);
5033
+ }
5034
+ })(type) : {};
5035
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5036
+ if (!test) {
5037
+ throw new Error(`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${type}`);
5038
+ }
5039
+ })(typeof type === 'string') : {};
5040
+ return this.recordArrayManager.liveArrayFor(normalizeModelName(type));
4730
5041
  }
4731
5042
 
4732
5043
  /**
@@ -4738,16 +5049,21 @@ class Store extends EmberObject {
4738
5049
  store.unloadAll('post');
4739
5050
  ```
4740
5051
  @method unloadAll
5052
+ @param {string} type the name of the resource
4741
5053
  @public
4742
- @param {String} modelName
4743
5054
  */
4744
- unloadAll(modelName) {
4745
- if (macroCondition(getOwnConfig().env.DEBUG)) {
5055
+
5056
+ unloadAll(type) {
5057
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
4746
5058
  assertDestroyedStoreOnly(this, 'unloadAll');
4747
5059
  }
4748
- assert(`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${String(modelName)}`, !modelName || typeof modelName === 'string');
5060
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5061
+ if (!test) {
5062
+ throw new Error(`Passing classes to store methods has been removed. Please pass a dasherized string instead of ${String(type)}`);
5063
+ }
5064
+ })(!type || typeof type === 'string') : {};
4749
5065
  this._join(() => {
4750
- if (modelName === undefined) {
5066
+ if (type === undefined) {
4751
5067
  // destroy the graph before unloadAll
4752
5068
  // since then we avoid churning relationships
4753
5069
  // during unload
@@ -4755,8 +5071,7 @@ class Store extends EmberObject {
4755
5071
  this.recordArrayManager.clear();
4756
5072
  this._instanceCache.clear();
4757
5073
  } else {
4758
- const normalizedModelName = normalizeModelName(modelName);
4759
- this._instanceCache.clear(normalizedModelName);
5074
+ this._instanceCache.clear(normalizeModelName(type));
4760
5075
  }
4761
5076
  });
4762
5077
  }
@@ -4893,7 +5208,7 @@ class Store extends EmberObject {
4893
5208
  */
4894
5209
 
4895
5210
  push(data) {
4896
- if (macroCondition(getOwnConfig().env.DEBUG)) {
5211
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
4897
5212
  assertDestroyingStore(this, 'push');
4898
5213
  }
4899
5214
  const pushed = this._push(data, false);
@@ -4915,10 +5230,10 @@ class Store extends EmberObject {
4915
5230
  @return {StableRecordIdentifier|Array<StableRecordIdentifier>|null} identifiers for the primary records that had data loaded
4916
5231
  */
4917
5232
  _push(jsonApiDoc, asyncFlush) {
4918
- if (macroCondition(getOwnConfig().env.DEBUG)) {
5233
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
4919
5234
  assertDestroyingStore(this, '_push');
4920
5235
  }
4921
- if (macroCondition(getOwnConfig().debug.LOG_PAYLOADS)) {
5236
+ if (macroCondition(getGlobalConfig().WarpDrive.debug.LOG_PAYLOADS)) {
4922
5237
  try {
4923
5238
  const data = JSON.parse(JSON.stringify(jsonApiDoc));
4924
5239
  // eslint-disable-next-line no-console
@@ -4944,17 +5259,23 @@ class Store extends EmberObject {
4944
5259
  /**
4945
5260
  * Trigger a save for a Record.
4946
5261
  *
5262
+ * Returns a promise resolving with the same record when the save is complete.
5263
+ *
4947
5264
  * @method saveRecord
4948
5265
  * @public
4949
- * @param {RecordInstance} record
5266
+ * @param {unknown} record
4950
5267
  * @param options
4951
- * @return {Promise<RecordInstance>}
5268
+ * @return {Promise<record>}
4952
5269
  */
4953
5270
  saveRecord(record, options = {}) {
4954
- if (macroCondition(getOwnConfig().env.DEBUG)) {
5271
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
4955
5272
  assertDestroyingStore(this, 'saveRecord');
4956
5273
  }
4957
- assert(`Unable to initate save for a record in a disconnected state`, storeFor(record));
5274
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5275
+ if (!test) {
5276
+ throw new Error(`Unable to initiate save for a record in a disconnected state`);
5277
+ }
5278
+ })(storeFor(record)) : {};
4958
5279
  const identifier = recordIdentifierFor(record);
4959
5280
  const cache = this.cache;
4960
5281
  if (!identifier) {
@@ -4962,8 +5283,11 @@ class Store extends EmberObject {
4962
5283
  // but just in case we reject here to prevent bad things.
4963
5284
  return Promise.reject(new Error(`Record Is Disconnected`));
4964
5285
  }
4965
- // TODO we used to check if the record was destroyed here
4966
- assert(`Cannot initiate a save request for an unloaded record: ${identifier.lid}`, this._instanceCache.recordIsLoaded(identifier));
5286
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5287
+ if (!test) {
5288
+ throw new Error(`Cannot initiate a save request for an unloaded record: ${identifier.lid}`);
5289
+ }
5290
+ })(this._instanceCache.recordIsLoaded(identifier)) : {};
4967
5291
  if (resourceIsFullyDeleted(this._instanceCache, identifier)) {
4968
5292
  return Promise.resolve(record);
4969
5293
  }
@@ -4987,11 +5311,6 @@ class Store extends EmberObject {
4987
5311
  [SkipCache]: true
4988
5312
  }
4989
5313
  };
4990
-
4991
- // we lie here on the type because legacy doesn't have enough context
4992
- cache.willCommit(identifier, {
4993
- request
4994
- });
4995
5314
  return this.request(request).then(document => document.content);
4996
5315
  }
4997
5316
 
@@ -5021,14 +5340,12 @@ class Store extends EmberObject {
5021
5340
  } = this._instanceCache;
5022
5341
  if (!cache) {
5023
5342
  cache = this._instanceCache.cache = this.createCache(this._instanceCache._storeWrapper);
5024
- if (macroCondition(getOwnConfig().env.DEBUG)) {
5343
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
5025
5344
  cache = new CacheManager(cache);
5026
5345
  }
5027
5346
  }
5028
5347
  return cache;
5029
5348
  }
5030
-
5031
- // @ts-expect-error
5032
5349
  destroy() {
5033
5350
  if (this.isDestroyed) {
5034
5351
  // @ember/test-helpers will call destroy multiple times
@@ -5047,16 +5364,67 @@ class Store extends EmberObject {
5047
5364
  return new this(args);
5048
5365
  }
5049
5366
  }
5367
+ if (macroCondition(getGlobalConfig().WarpDrive.deprecations.ENABLE_LEGACY_SCHEMA_SERVICE)) {
5368
+ Store.prototype.getSchemaDefinitionService = function () {
5369
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5370
+ if (!test) {
5371
+ throw new Error(`You must registerSchemaDefinitionService with the store to use custom model classes`);
5372
+ }
5373
+ })(this._schema) : {};
5374
+ deprecate(`Use \`store.schema\` instead of \`store.getSchemaDefinitionService()\``, false, {
5375
+ id: 'ember-data:schema-service-updates',
5376
+ until: '5.0',
5377
+ for: 'ember-data',
5378
+ since: {
5379
+ available: '5.4',
5380
+ enabled: '5.4'
5381
+ }
5382
+ });
5383
+ return this._schema;
5384
+ };
5385
+ Store.prototype.registerSchemaDefinitionService = function (schema) {
5386
+ deprecate(`Use \`store.createSchemaService\` instead of \`store.registerSchemaDefinitionService()\``, false, {
5387
+ id: 'ember-data:schema-service-updates',
5388
+ until: '5.0',
5389
+ for: 'ember-data',
5390
+ since: {
5391
+ available: '5.4',
5392
+ enabled: '5.4'
5393
+ }
5394
+ });
5395
+ this._schema = schema;
5396
+ };
5397
+ Store.prototype.registerSchema = function (schema) {
5398
+ deprecate(`Use \`store.createSchemaService\` instead of \`store.registerSchema()\``, false, {
5399
+ id: 'ember-data:schema-service-updates',
5400
+ until: '5.0',
5401
+ for: 'ember-data',
5402
+ since: {
5403
+ available: '5.4',
5404
+ enabled: '5.4'
5405
+ }
5406
+ });
5407
+ this._schema = schema;
5408
+ };
5409
+ }
5050
5410
  let assertDestroyingStore;
5051
5411
  let assertDestroyedStoreOnly;
5052
- if (macroCondition(getOwnConfig().env.DEBUG)) {
5412
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
5053
5413
  // eslint-disable-next-line @typescript-eslint/no-shadow
5054
5414
  assertDestroyingStore = function assertDestroyingStore(store, method) {
5055
- assert(`Attempted to call store.${method}(), but the store instance has already been destroyed.`, !(store.isDestroying || store.isDestroyed));
5415
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5416
+ if (!test) {
5417
+ throw new Error(`Attempted to call store.${method}(), but the store instance has already been destroyed.`);
5418
+ }
5419
+ })(!(store.isDestroying || store.isDestroyed)) : {};
5056
5420
  };
5057
5421
  // eslint-disable-next-line @typescript-eslint/no-shadow
5058
5422
  assertDestroyedStoreOnly = function assertDestroyedStoreOnly(store, method) {
5059
- assert(`Attempted to call store.${method}(), but the store instance has already been destroyed.`, !store.isDestroyed);
5423
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5424
+ if (!test) {
5425
+ throw new Error(`Attempted to call store.${method}(), but the store instance has already been destroyed.`);
5426
+ }
5427
+ })(!store.isDestroyed) : {};
5060
5428
  };
5061
5429
  }
5062
5430
  function isMaybeIdentifier(maybeIdentifier) {
@@ -5066,33 +5434,38 @@ function normalizeProperties(store, identifier, properties) {
5066
5434
  // assert here
5067
5435
  if (properties !== undefined) {
5068
5436
  if ('id' in properties) {
5069
- assert(`expected id to be a string or null`, properties.id !== undefined);
5437
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5438
+ if (!test) {
5439
+ throw new Error(`expected id to be a string or null`);
5440
+ }
5441
+ })(properties.id !== undefined) : {};
5070
5442
  }
5071
- assert(`You passed '${typeof properties}' as properties for record creation instead of an object.`, typeof properties === 'object' && properties !== null);
5443
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5444
+ if (!test) {
5445
+ throw new Error(`You passed '${typeof properties}' as properties for record creation instead of an object.`);
5446
+ }
5447
+ })(typeof properties === 'object' && properties !== null) : {};
5072
5448
  const {
5073
5449
  type
5074
5450
  } = identifier;
5075
5451
 
5076
5452
  // convert relationship Records to RecordDatas before passing to RecordData
5077
- const defs = store.getSchemaDefinitionService().relationshipsDefinitionFor({
5453
+ const defs = store.schema.fields({
5078
5454
  type
5079
5455
  });
5080
- if (defs !== null) {
5456
+ if (defs.size) {
5081
5457
  const keys = Object.keys(properties);
5082
- let relationshipValue;
5083
5458
  for (let i = 0; i < keys.length; i++) {
5084
5459
  const prop = keys[i];
5085
- const def = defs[prop];
5086
- if (def !== undefined) {
5087
- if (def.kind === 'hasMany') {
5088
- if (macroCondition(getOwnConfig().env.DEBUG)) {
5089
- assertRecordsPassedToHasMany(properties[prop]);
5090
- }
5091
- relationshipValue = extractIdentifiersFromRecords(properties[prop]);
5092
- } else {
5093
- relationshipValue = extractIdentifierFromRecord(properties[prop]);
5460
+ const field = defs.get(prop);
5461
+ if (!field) continue;
5462
+ if (field.kind === 'hasMany') {
5463
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
5464
+ assertRecordsPassedToHasMany(properties[prop]);
5094
5465
  }
5095
- properties[prop] = relationshipValue;
5466
+ properties[prop] = extractIdentifiersFromRecords(properties[prop]);
5467
+ } else if (field.kind === 'belongsTo') {
5468
+ properties[prop] = extractIdentifierFromRecord(properties[prop]);
5096
5469
  }
5097
5470
  }
5098
5471
  }
@@ -5100,8 +5473,16 @@ function normalizeProperties(store, identifier, properties) {
5100
5473
  return properties;
5101
5474
  }
5102
5475
  function assertRecordsPassedToHasMany(records) {
5103
- assert(`You must pass an array of records to set a hasMany relationship`, Array.isArray(records));
5104
- assert(`All elements of a hasMany relationship must be instances of Model, you passed ${records.map(r => `${typeof r}`).join(', ')}`, function () {
5476
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5477
+ if (!test) {
5478
+ throw new Error(`You must pass an array of records to set a hasMany relationship`);
5479
+ }
5480
+ })(Array.isArray(records)) : {};
5481
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5482
+ if (!test) {
5483
+ throw new Error(`All elements of a hasMany relationship must be instances of Model, you passed ${records.map(r => `${typeof r}`).join(', ')}`);
5484
+ }
5485
+ })(function () {
5105
5486
  return records.every(record => {
5106
5487
  try {
5107
5488
  recordIdentifierFor(record);
@@ -5110,7 +5491,7 @@ function assertRecordsPassedToHasMany(records) {
5110
5491
  return false;
5111
5492
  }
5112
5493
  });
5113
- }());
5494
+ }()) : {};
5114
5495
  }
5115
5496
  function extractIdentifiersFromRecords(records) {
5116
5497
  return records.map(record => extractIdentifierFromRecord(record));
@@ -5122,6 +5503,10 @@ function extractIdentifierFromRecord(recordOrPromiseRecord) {
5122
5503
  const extract = recordIdentifierFor;
5123
5504
  return extract(recordOrPromiseRecord);
5124
5505
  }
5506
+
5507
+ /**
5508
+ * @module @ember-data/store
5509
+ */
5125
5510
  function urlFromLink(link) {
5126
5511
  if (typeof link === 'string') return link;
5127
5512
  return link.href;
@@ -5139,69 +5524,79 @@ function urlFromLink(link) {
5139
5524
  * @public
5140
5525
  * @class Document
5141
5526
  */
5142
- var _store = /*#__PURE__*/_classPrivateFieldKey("store");
5143
- var _request = /*#__PURE__*/_classPrivateFieldKey("request");
5144
5527
  class Document {
5528
+ /**
5529
+ * The links object for this document, if any
5530
+ *
5531
+ * e.g.
5532
+ *
5533
+ * ```
5534
+ * {
5535
+ * self: '/articles?page[number]=3',
5536
+ * }
5537
+ * ```
5538
+ *
5539
+ * @property links
5540
+ * @type {object|undefined} - a links object
5541
+ * @public
5542
+ */
5543
+
5544
+ /**
5545
+ * The primary data for this document, if any.
5546
+ *
5547
+ * If this document has no primary data (e.g. because it is an error document)
5548
+ * this property will be `undefined`.
5549
+ *
5550
+ * For collections this will be an array of record instances,
5551
+ * for single resource requests it will be a single record instance or null.
5552
+ *
5553
+ * @property data
5554
+ * @public
5555
+ * @type {object|Array<object>|null|undefined} - a data object
5556
+ */
5557
+
5558
+ /**
5559
+ * The errors returned by the API for this request, if any
5560
+ *
5561
+ * @property errors
5562
+ * @public
5563
+ * @type {object|undefined} - an errors object
5564
+ */
5565
+
5566
+ /**
5567
+ * The meta object for this document, if any
5568
+ *
5569
+ * @property meta
5570
+ * @public
5571
+ * @type {object|undefined} - a meta object
5572
+ */
5573
+
5574
+ /**
5575
+ * The identifier associated with this document, if any
5576
+ *
5577
+ * @property identifier
5578
+ * @public
5579
+ * @type {StableDocumentIdentifier|null}
5580
+ */
5581
+
5582
+ #store;
5145
5583
  constructor(store, identifier) {
5146
- Object.defineProperty(this, _request, {
5147
- value: _request2
5148
- });
5149
- /**
5150
- * The links object for this document, if any
5151
- *
5152
- * e.g.
5153
- *
5154
- * ```
5155
- * {
5156
- * self: '/articles?page[number]=3',
5157
- * }
5158
- * ```
5159
- *
5160
- * @property links
5161
- * @type {object|undefined} - a links object
5162
- * @public
5163
- */
5164
- /**
5165
- * The primary data for this document, if any.
5166
- *
5167
- * If this document has no primary data (e.g. because it is an error document)
5168
- * this property will be `undefined`.
5169
- *
5170
- * For collections this will be an array of record instances,
5171
- * for single resource requests it will be a single record instance or null.
5172
- *
5173
- * @property data
5174
- * @public
5175
- * @type {object|Array<object>|null|undefined} - a data object
5176
- */
5177
- /**
5178
- * The errors returned by the API for this request, if any
5179
- *
5180
- * @property errors
5181
- * @public
5182
- * @type {object|undefined} - an errors object
5183
- */
5184
- /**
5185
- * The meta object for this document, if any
5186
- *
5187
- * @property meta
5188
- * @public
5189
- * @type {object|undefined} - a meta object
5190
- */
5191
- /**
5192
- * The identifier associated with this document, if any
5193
- *
5194
- * @property identifier
5195
- * @public
5196
- * @type {StableDocumentIdentifier|null}
5197
- */
5198
- Object.defineProperty(this, _store, {
5199
- writable: true,
5200
- value: void 0
5201
- });
5202
- _classPrivateFieldBase(this, _store)[_store] = store;
5584
+ this.#store = store;
5203
5585
  this.identifier = identifier;
5204
5586
  }
5587
+ async #request(link, options) {
5588
+ const href = this.links?.[link];
5589
+ if (!href) {
5590
+ return null;
5591
+ }
5592
+ options.method = options.method || 'GET';
5593
+ Object.assign(options, {
5594
+ url: urlFromLink(href)
5595
+ });
5596
+ const response = await this.#store.request(options);
5597
+ return response.content;
5598
+ }
5599
+
5205
5600
  /**
5206
5601
  * Fetches the related link for this document, returning a promise that resolves
5207
5602
  * with the document when the request completes. If no related link is present,
@@ -5213,10 +5608,14 @@ class Document {
5213
5608
  * @return Promise<Document>
5214
5609
  */
5215
5610
  fetch(options = {}) {
5216
- assert(`No self or related link`, this.links?.related || this.links?.self);
5611
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5612
+ if (!test) {
5613
+ throw new Error(`No self or related link`);
5614
+ }
5615
+ })(this.links?.related || this.links?.self) : {};
5217
5616
  options.cacheOptions = options.cacheOptions || {};
5218
5617
  options.cacheOptions.key = this.identifier?.lid;
5219
- return _classPrivateFieldBase(this, _request)[_request](this.links.related ? 'related' : 'self', options);
5618
+ return this.#request(this.links.related ? 'related' : 'self', options);
5220
5619
  }
5221
5620
 
5222
5621
  /**
@@ -5230,7 +5629,7 @@ class Document {
5230
5629
  * @return Promise<Document | null>
5231
5630
  */
5232
5631
  next(options = {}) {
5233
- return _classPrivateFieldBase(this, _request)[_request]('next', options);
5632
+ return this.#request('next', options);
5234
5633
  }
5235
5634
 
5236
5635
  /**
@@ -5244,7 +5643,7 @@ class Document {
5244
5643
  * @return Promise<Document | null>
5245
5644
  */
5246
5645
  prev(options = {}) {
5247
- return _classPrivateFieldBase(this, _request)[_request]('prev', options);
5646
+ return this.#request('prev', options);
5248
5647
  }
5249
5648
 
5250
5649
  /**
@@ -5258,7 +5657,7 @@ class Document {
5258
5657
  * @return Promise<Document | null>
5259
5658
  */
5260
5659
  first(options = {}) {
5261
- return _classPrivateFieldBase(this, _request)[_request]('first', options);
5660
+ return this.#request('first', options);
5262
5661
  }
5263
5662
 
5264
5663
  /**
@@ -5272,7 +5671,7 @@ class Document {
5272
5671
  * @return Promise<Document | null>
5273
5672
  */
5274
5673
  last(options = {}) {
5275
- return _classPrivateFieldBase(this, _request)[_request]('last', options);
5674
+ return this.#request('last', options);
5276
5675
  }
5277
5676
 
5278
5677
  /**
@@ -5306,17 +5705,6 @@ class Document {
5306
5705
  return data;
5307
5706
  }
5308
5707
  }
5309
- async function _request2(link, options) {
5310
- const href = this.links?.[link];
5311
- if (!href) {
5312
- return null;
5313
- }
5314
- options.method = options.method || 'GET';
5315
- const response = await _classPrivateFieldBase(this, _store)[_store].request(Object.assign(options, {
5316
- url: urlFromLink(href)
5317
- }));
5318
- return response.content;
5319
- }
5320
5708
  defineSignal(Document.prototype, 'data');
5321
5709
  defineSignal(Document.prototype, 'links');
5322
5710
  defineSignal(Document.prototype, 'errors');
@@ -5337,10 +5725,9 @@ defineSignal(Document.prototype, 'meta');
5337
5725
  * Implementing this service allows you to programatically define
5338
5726
  * when a request should be considered expired.
5339
5727
  *
5340
- * @class <Interface> LifetimesService
5728
+ * @class <Interface> CachePolicy
5341
5729
  * @public
5342
5730
  */
5343
-
5344
5731
  const MUTATION_OPS = new Set(['createRecord', 'updateRecord', 'deleteRecord']);
5345
5732
  function isErrorDocument(document) {
5346
5733
  return 'errors' in document;
@@ -5349,6 +5736,14 @@ function maybeUpdateUiObjects(store, request, options, document, isFromCache) {
5349
5736
  const {
5350
5737
  identifier
5351
5738
  } = options;
5739
+ if (!document) {
5740
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5741
+ if (!test) {
5742
+ throw new Error(`The CacheHandler expected response content but none was found`);
5743
+ }
5744
+ })(!options.shouldHydrate) : {};
5745
+ return document;
5746
+ }
5352
5747
  if (isErrorDocument(document)) {
5353
5748
  if (!identifier && !options.shouldHydrate) {
5354
5749
  return document;
@@ -5446,7 +5841,7 @@ function calcShouldBackgroundFetch(store, request, willFetch, identifier) {
5446
5841
  const {
5447
5842
  cacheOptions
5448
5843
  } = request;
5449
- return !willFetch && (cacheOptions?.backgroundReload || (store.lifetimes && identifier ? store.lifetimes.isSoftExpired(identifier, store) : false));
5844
+ return cacheOptions?.backgroundReload || (store.lifetimes && identifier ? store.lifetimes.isSoftExpired(identifier, store) : false);
5450
5845
  }
5451
5846
  function isMutation(request) {
5452
5847
  return Boolean(request.op && MUTATION_OPS.has(request.op));
@@ -5461,8 +5856,14 @@ function fetchContentAndHydrate(next, context, identifier, shouldFetch, shouldBa
5461
5856
  isMut = true;
5462
5857
  // TODO should we handle multiple records in request.records by iteratively calling willCommit for each
5463
5858
  const record = context.request.data?.record || context.request.records?.[0];
5464
- assert(`Expected to receive a list of records included in the ${context.request.op} request`, record);
5465
- store.cache.willCommit(record, context);
5859
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5860
+ if (!test) {
5861
+ throw new Error(`Expected to receive a list of records included in the ${context.request.op} request`);
5862
+ }
5863
+ })(record || !shouldHydrate) : {};
5864
+ if (record) {
5865
+ store.cache.willCommit(record, context);
5866
+ }
5466
5867
  }
5467
5868
  if (store.lifetimes?.willRequest) {
5468
5869
  store.lifetimes.willRequest(context.request, identifier, store);
@@ -5474,7 +5875,15 @@ function fetchContentAndHydrate(next, context, identifier, shouldFetch, shouldBa
5474
5875
  store._join(() => {
5475
5876
  if (isMutation(context.request)) {
5476
5877
  const record = context.request.data?.record || context.request.records?.[0];
5477
- response = store.cache.didCommit(record, document);
5878
+ if (record) {
5879
+ response = store.cache.didCommit(record, document);
5880
+
5881
+ // a mutation combined with a 204 has no cache impact when no known records were involved
5882
+ // a createRecord with a 201 with an empty response and no known records should similarly
5883
+ // have no cache impact
5884
+ } else if (isCacheAffecting(document)) {
5885
+ response = store.cache.put(document);
5886
+ }
5478
5887
  } else {
5479
5888
  response = store.cache.put(document);
5480
5889
  }
@@ -5536,7 +5945,11 @@ function fetchContentAndHydrate(next, context, identifier, shouldFetch, shouldBa
5536
5945
  if (!isMut) {
5537
5946
  return promise;
5538
5947
  }
5539
- assert(`Expected a mutation`, isMutation(context.request));
5948
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5949
+ if (!test) {
5950
+ throw new Error(`Expected a mutation`);
5951
+ }
5952
+ })(isMutation(context.request)) : {};
5540
5953
 
5541
5954
  // for mutations we need to enqueue the promise with the requestStateService
5542
5955
  // TODO should we enque a request per record in records?
@@ -5549,12 +5962,62 @@ function fetchContentAndHydrate(next, context, identifier, shouldFetch, shouldBa
5549
5962
  }]
5550
5963
  });
5551
5964
  }
5965
+ function isAggregateError(error) {
5966
+ return error instanceof AggregateError || error.name === 'AggregateError' && Array.isArray(error.errors);
5967
+ }
5968
+ // TODO @runspired, consider if we should deep freeze errors (potentially only in debug) vs cloning them
5552
5969
  function cloneError(error) {
5553
- const cloned = new Error(error.message);
5970
+ const isAggregate = isAggregateError(error);
5971
+ const cloned = isAggregate ? new AggregateError(structuredClone(error.errors), error.message) : new Error(error.message);
5554
5972
  cloned.stack = error.stack;
5555
5973
  cloned.error = error.error;
5974
+
5975
+ // copy over enumerable properties
5976
+ Object.assign(cloned, error);
5556
5977
  return cloned;
5557
5978
  }
5979
+
5980
+ /**
5981
+ * A CacheHandler that adds support for using an EmberData Cache with a RequestManager.
5982
+ *
5983
+ * This handler will only run when a request has supplied a `store` instance. Requests
5984
+ * issued by the store via `store.request()` will automatically have the `store` instance
5985
+ * attached to the request.
5986
+ *
5987
+ * ```ts
5988
+ * requestManager.request({
5989
+ * store: store,
5990
+ * url: '/api/posts',
5991
+ * method: 'GET'
5992
+ * });
5993
+ * ```
5994
+ *
5995
+ * When this handler elects to handle a request, it will return the raw `StructuredDocument`
5996
+ * unless the request has `[EnableHydration]` set to `true`. In this case, the handler will
5997
+ * return a `Document` instance that will automatically update the UI when the cache is updated
5998
+ * in the future and will hydrate any identifiers in the StructuredDocument into Record instances.
5999
+ *
6000
+ * When issuing a request via the store, [EnableHydration] is automatically set to `true`. This
6001
+ * means that if desired you can issue requests that utilize the cache without needing to also
6002
+ * utilize Record instances if desired.
6003
+ *
6004
+ * Said differently, you could elect to issue all requests via a RequestManager, without ever using
6005
+ * the store directly, by setting [EnableHydration] to `true` and providing a store instance. Not
6006
+ * necessarily the most useful thing, but the decoupled nature of the RequestManager and incremental-feature
6007
+ * approach of EmberData allows for this flexibility.
6008
+ *
6009
+ * ```ts
6010
+ * import { EnableHydration } from '@warp-drive/core-types/request';
6011
+ *
6012
+ * requestManager.request({
6013
+ * store: store,
6014
+ * url: '/api/posts',
6015
+ * method: 'GET',
6016
+ * [EnableHydration]: true
6017
+ * });
6018
+ *
6019
+ * @typedoc
6020
+ */
5558
6021
  const CacheHandler = {
5559
6022
  request(context, next) {
5560
6023
  // if we have no cache or no cache-key skip cache handling
@@ -5577,7 +6040,13 @@ const CacheHandler = {
5577
6040
  const promise = fetchContentAndHydrate(next, context, identifier, false, true);
5578
6041
  store.requestManager._pending.set(context.id, promise);
5579
6042
  }
6043
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
6044
+ if (!test) {
6045
+ throw new Error(`Expected a peeked request to be present`);
6046
+ }
6047
+ })(peeked) : {};
5580
6048
  const shouldHydrate = context.request[EnableHydration] || false;
6049
+ context.setResponse(peeked.response);
5581
6050
  if ('error' in peeked) {
5582
6051
  const content = shouldHydrate ? maybeUpdateUiObjects(store, context.request, {
5583
6052
  shouldHydrate,
@@ -5587,10 +6056,11 @@ const CacheHandler = {
5587
6056
  newError.content = content;
5588
6057
  throw newError;
5589
6058
  }
5590
- return Promise.resolve(shouldHydrate ? maybeUpdateUiObjects(store, context.request, {
6059
+ const result = shouldHydrate ? maybeUpdateUiObjects(store, context.request, {
5591
6060
  shouldHydrate,
5592
6061
  identifier
5593
- }, peeked.content, true) : peeked.content);
6062
+ }, peeked.content, true) : peeked.content;
6063
+ return result;
5594
6064
  }
5595
6065
  };
5596
6066
  function copyDocumentProperties(target, source) {
@@ -5604,4 +6074,17 @@ function copyDocumentProperties(target, source) {
5604
6074
  target.errors = source.errors;
5605
6075
  }
5606
6076
  }
5607
- 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, coerceId as e, Collection as f, SOURCE as g, fastPush as h, isStableIdentifier as i, removeRecordDataFor as j, setRecordIdentifier as k, StoreMap as l, setCacheFor as m, notifyArray as n, normalizeModelName as o, peekCache as p, recordIdentifierFor as r, storeFor as s };
6077
+ function isCacheAffecting(document) {
6078
+ if (!isMutation(document.request)) {
6079
+ return true;
6080
+ }
6081
+ // a mutation combined with a 204 has no cache impact when no known records were involved
6082
+ // a createRecord with a 201 with an empty response and no known records should similarly
6083
+ // have no cache impact
6084
+
6085
+ if (document.request.op === 'createRecord' && document.response?.status === 201) {
6086
+ return document.content ? Object.keys(document.content).length > 0 : false;
6087
+ }
6088
+ return document.response?.status !== 204;
6089
+ }
6090
+ 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 };