@ember-data/store 4.8.0-alpha.3 → 4.8.0-alpha.4

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.
@@ -4,6 +4,8 @@
4
4
  import { assert, warn } from '@ember/debug';
5
5
  import { DEBUG } from '@glimmer/env';
6
6
 
7
+ import { getOwnConfig, importSync, macroCondition } from '@embroider/macros';
8
+
7
9
  import { LOG_IDENTIFIERS } from '@ember-data/private-build-infra/debugging';
8
10
  import type { ExistingResourceObject, ResourceIdentifierObject } from '@ember-data/types/q/ember-data-json-api';
9
11
  import type {
@@ -34,6 +36,10 @@ export function isStableIdentifier(identifier: Object): identifier is StableReco
34
36
  const isFastBoot = typeof FastBoot !== 'undefined';
35
37
  const _crypto: Crypto = isFastBoot ? (FastBoot.require('crypto') as Crypto) : window.crypto;
36
38
 
39
+ if (macroCondition(getOwnConfig<{ polyfillUUID: boolean }>().polyfillUUID)) {
40
+ importSync('./utils/uuid-polyfill');
41
+ }
42
+
37
43
  function uuidv4(): string {
38
44
  return _crypto.randomUUID();
39
45
  }
@@ -48,7 +54,6 @@ function freeze<T>(obj: T): T {
48
54
  interface KeyOptions {
49
55
  lid: IdentifierMap;
50
56
  id: IdentifierMap;
51
- _allIdentifiers: StableRecordIdentifier[];
52
57
  }
53
58
 
54
59
  type IdentifierMap = ConfidentDict<StableRecordIdentifier>;
@@ -115,19 +120,15 @@ if (DEBUG) {
115
120
  @public
116
121
  */
117
122
  export class IdentifierCache {
118
- // Typescript still leaks private properties in the final
119
- // compiled class, so we may want to move these from _underscore
120
- // to a WeakMap to avoid leaking
121
- // currently we leak this for test purposes
122
123
  _cache = {
123
124
  lids: Object.create(null) as IdentifierMap,
124
125
  types: Object.create(null) as TypeMap,
125
126
  };
126
- private _generate: GenerationMethod;
127
- private _update: UpdateMethod;
128
- private _forget: ForgetMethod;
129
- private _reset: ResetMethod;
130
- private _merge: MergeMethod;
127
+ declare _generate: GenerationMethod;
128
+ declare _update: UpdateMethod;
129
+ declare _forget: ForgetMethod;
130
+ declare _reset: ResetMethod;
131
+ declare _merge: MergeMethod;
131
132
 
132
133
  constructor() {
133
134
  // we cache the user configuredGenerationMethod at init because it must
@@ -156,12 +157,9 @@ export class IdentifierCache {
156
157
  * @method _getRecordIdentifier
157
158
  * @private
158
159
  */
159
- private _getRecordIdentifier(resource: ResourceIdentifierObject, shouldGenerate: true): StableRecordIdentifier;
160
- private _getRecordIdentifier(
161
- resource: ResourceIdentifierObject,
162
- shouldGenerate: false
163
- ): StableRecordIdentifier | undefined;
164
- private _getRecordIdentifier(
160
+ _getRecordIdentifier(resource: ResourceIdentifierObject, shouldGenerate: true): StableRecordIdentifier;
161
+ _getRecordIdentifier(resource: ResourceIdentifierObject, shouldGenerate: false): StableRecordIdentifier | undefined;
162
+ _getRecordIdentifier(
165
163
  resource: ResourceIdentifierObject,
166
164
  shouldGenerate: boolean = false
167
165
  ): StableRecordIdentifier | undefined {
@@ -169,7 +167,7 @@ export class IdentifierCache {
169
167
  if (isStableIdentifier(resource)) {
170
168
  if (DEBUG) {
171
169
  // TODO should we instead just treat this case as a new generation skipping the short circuit?
172
- if (!(resource.lid in this._cache.lids) || this._cache.lids[resource.lid] !== resource) {
170
+ if (!(this._cache.lids[resource.lid] !== undefined) || this._cache.lids[resource.lid] !== resource) {
173
171
  throw new Error(`The supplied identifier ${resource} does not belong to this store instance`);
174
172
  }
175
173
  }
@@ -197,7 +195,7 @@ export class IdentifierCache {
197
195
  }
198
196
 
199
197
  if (shouldGenerate === false) {
200
- if (!('type' in resource) || !('id' in resource) || !resource.type || !resource.id) {
198
+ if (!(resource as ExistingResourceObject).type || !(resource as ExistingResourceObject).id) {
201
199
  return;
202
200
  }
203
201
  }
@@ -252,7 +250,7 @@ export class IdentifierCache {
252
250
  if (DEBUG) {
253
251
  // realistically if you hit this it means you changed `type` :/
254
252
  // TODO consider how to handle type change assertions more gracefully
255
- if (identifier.lid in this._cache.lids) {
253
+ if (this._cache.lids[identifier.lid] !== undefined) {
256
254
  throw new Error(`You should not change the <type> of a RecordIdentifier`);
257
255
  }
258
256
  }
@@ -262,9 +260,6 @@ export class IdentifierCache {
262
260
  // TODO consider having the `lid` cache be
263
261
  // one level up
264
262
  keyOptions.lid[identifier.lid] = identifier;
265
- // TODO exists temporarily to support `peekAll`
266
- // but likely to move
267
- keyOptions._allIdentifiers.push(identifier);
268
263
 
269
264
  if (LOG_IDENTIFIERS && shouldGenerate) {
270
265
  // eslint-disable-next-line no-console
@@ -360,7 +355,7 @@ export class IdentifierCache {
360
355
 
361
356
  // populate our unique table
362
357
  if (DEBUG) {
363
- if (identifier.lid in this._cache.lids) {
358
+ if (this._cache.lids[identifier.lid] !== undefined) {
364
359
  throw new Error(`The lid generated for the new record is not unique as it matches an existing identifier`);
365
360
  }
366
361
  }
@@ -368,9 +363,6 @@ export class IdentifierCache {
368
363
 
369
364
  // populate the type+lid cache
370
365
  keyOptions.lid[newLid] = identifier;
371
- // ensure a peekAll sees our new identifier too
372
- // TODO move this outta here?
373
- keyOptions._allIdentifiers.push(identifier);
374
366
 
375
367
  if (LOG_IDENTIFIERS) {
376
368
  // eslint-disable-next-line no-console
@@ -405,13 +397,17 @@ export class IdentifierCache {
405
397
  updateRecordIdentifier(identifierObject: RecordIdentifier, data: ResourceData): StableRecordIdentifier {
406
398
  let identifier = this.getOrCreateRecordIdentifier(identifierObject);
407
399
 
408
- let newId = 'id' in data ? coerceId(data.id) : null;
400
+ let newId =
401
+ (data as ExistingResourceObject).id !== undefined ? coerceId((data as ExistingResourceObject).id) : null;
409
402
  let existingIdentifier = detectMerge(this._cache.types, identifier, data, newId, this._cache.lids);
410
403
 
411
404
  if (!existingIdentifier) {
412
405
  // If the incoming type does not match the identifier type, we need to create an identifier for the incoming
413
406
  // data so we can merge the incoming data with the existing identifier, see #7325 and #7363
414
- if ('type' in data && data.type && identifier.type !== normalizeModelName(data.type)) {
407
+ if (
408
+ (data as ExistingResourceObject).type &&
409
+ identifier.type !== normalizeModelName((data as ExistingResourceObject).type)
410
+ ) {
415
411
  let incomingDataResource = { ...data };
416
412
  // Need to strip the lid from the incomingData in order force a new identifier creation
417
413
  delete incomingDataResource.lid;
@@ -455,7 +451,7 @@ export class IdentifierCache {
455
451
  keyOptions.id[newId] = identifier;
456
452
 
457
453
  if (id !== null) {
458
- delete keyOptions.id[id];
454
+ keyOptions.id[id] = undefined as unknown as StableRecordIdentifier;
459
455
  }
460
456
  } else if (LOG_IDENTIFIERS) {
461
457
  // eslint-disable-next-line no-console
@@ -511,13 +507,10 @@ export class IdentifierCache {
511
507
  let identifier = this.getOrCreateRecordIdentifier(identifierObject);
512
508
  let keyOptions = getTypeIndex(this._cache.types, identifier.type);
513
509
  if (identifier.id !== null) {
514
- delete keyOptions.id[identifier.id];
510
+ keyOptions.id[identifier.id] = undefined as unknown as StableRecordIdentifier;
515
511
  }
516
- delete this._cache.lids[identifier.lid];
517
- delete keyOptions.lid[identifier.lid];
518
-
519
- let index = keyOptions._allIdentifiers.indexOf(identifier);
520
- keyOptions._allIdentifiers.splice(index, 1);
512
+ this._cache.lids[identifier.lid] = undefined as unknown as StableRecordIdentifier;
513
+ keyOptions.lid[identifier.lid] = undefined as unknown as StableRecordIdentifier;
521
514
 
522
515
  IDENTIFIERS.delete(identifierObject);
523
516
  this._forget(identifier, 'record');
@@ -539,7 +532,6 @@ function getTypeIndex(typeMap: TypeMap, type: string): KeyOptions {
539
532
  typeIndex = {
540
533
  lid: Object.create(null),
541
534
  id: Object.create(null),
542
- _allIdentifiers: [],
543
535
  };
544
536
  typeMap[type] = typeIndex;
545
537
  }
@@ -643,8 +635,8 @@ function performRecordIdentifierUpdate(identifier: StableRecordIdentifier, data:
643
635
  // for the multiple-cache-key scenario we "could"
644
636
  // use a heuristic to guess the best id for display
645
637
  // (usually when `data.id` is available and `data.attributes` is not)
646
- if ('id' in data && data.id !== undefined) {
647
- identifier.id = coerceId(data.id);
638
+ if ((data as ExistingResourceObject).id !== undefined) {
639
+ identifier.id = coerceId((data as ExistingResourceObject).id);
648
640
  }
649
641
  }
650
642
 
@@ -662,7 +654,7 @@ function detectMerge(
662
654
 
663
655
  return existingIdentifier !== undefined ? existingIdentifier : false;
664
656
  } else {
665
- let newType = 'type' in data && data.type && normalizeModelName(data.type);
657
+ let newType = (data as ExistingResourceObject).type && normalizeModelName((data as ExistingResourceObject).type);
666
658
 
667
659
  // If the ids and type are the same but lid is not the same, we should trigger a merge of the identifiers
668
660
  if (id !== null && id === newId && newType === type && data.lid && data.lid !== lid) {