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

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.
@@ -25,9 +25,8 @@ import coerceId from '../utils/coerce-id';
25
25
  import { DEBUG_CLIENT_ORIGINATED, DEBUG_IDENTIFIER_BUCKET } from '../utils/identifer-debug-consts';
26
26
  import isNonEmptyString from '../utils/is-non-empty-string';
27
27
  import normalizeModelName from '../utils/normalize-model-name';
28
- import WeakCache from '../utils/weak-cache';
29
28
 
30
- const IDENTIFIERS = new WeakSet();
29
+ const IDENTIFIERS = new Set();
31
30
 
32
31
  export function isStableIdentifier(identifier: Object): identifier is StableRecordIdentifier {
33
32
  return IDENTIFIERS.has(identifier);
@@ -56,7 +55,7 @@ interface KeyOptions {
56
55
  id: IdentifierMap;
57
56
  }
58
57
 
59
- type IdentifierMap = ConfidentDict<StableRecordIdentifier>;
58
+ type IdentifierMap = Map<string, StableRecordIdentifier>;
60
59
  type TypeMap = ConfidentDict<KeyOptions>;
61
60
  export type MergeMethod = (
62
61
  targetIdentifier: StableRecordIdentifier,
@@ -85,12 +84,15 @@ export function setIdentifierResetMethod(method: ResetMethod | null): void {
85
84
  configuredResetMethod = method;
86
85
  }
87
86
 
87
+ type WithLid = { lid: string };
88
+ type WithId = { id: string | null; type: string };
89
+
88
90
  function defaultGenerationMethod(data: ResourceData | { type: string }, bucket: IdentifierBucket): string {
89
- if ('lid' in data && isNonEmptyString(data.lid)) {
90
- return data.lid;
91
+ if (isNonEmptyString((data as WithLid).lid)) {
92
+ return (data as WithLid).lid;
91
93
  }
92
- if ('id' in data) {
93
- let { type, id } = data;
94
+ if ((data as WithId).id !== undefined) {
95
+ let { type, id } = data as WithId;
94
96
  // TODO: add test for id not a string
95
97
  if (isNonEmptyString(coerceId(id))) {
96
98
  return `@lid:${normalizeModelName(type)}-${id}`;
@@ -103,7 +105,7 @@ function defaultEmptyCallback(...args: any[]): any {}
103
105
 
104
106
  let DEBUG_MAP;
105
107
  if (DEBUG) {
106
- DEBUG_MAP = new WeakCache<StableRecordIdentifier, StableRecordIdentifier>('identifier-proxy-target');
108
+ DEBUG_MAP = new WeakMap<StableRecordIdentifier, StableRecordIdentifier>();
107
109
  }
108
110
 
109
111
  /**
@@ -121,7 +123,7 @@ if (DEBUG) {
121
123
  */
122
124
  export class IdentifierCache {
123
125
  _cache = {
124
- lids: Object.create(null) as IdentifierMap,
126
+ lids: new Map<string, StableRecordIdentifier>(),
125
127
  types: Object.create(null) as TypeMap,
126
128
  };
127
129
  declare _generate: GenerationMethod;
@@ -129,6 +131,7 @@ export class IdentifierCache {
129
131
  declare _forget: ForgetMethod;
130
132
  declare _reset: ResetMethod;
131
133
  declare _merge: MergeMethod;
134
+ declare _isDefaultConfig: boolean;
132
135
 
133
136
  constructor() {
134
137
  // we cache the user configuredGenerationMethod at init because it must
@@ -138,6 +141,7 @@ export class IdentifierCache {
138
141
  this._forget = configuredForgetMethod || defaultEmptyCallback;
139
142
  this._reset = configuredResetMethod || defaultEmptyCallback;
140
143
  this._merge = defaultEmptyCallback;
144
+ this._isDefaultConfig = !configuredGenerationMethod;
141
145
  }
142
146
 
143
147
  /**
@@ -167,7 +171,7 @@ export class IdentifierCache {
167
171
  if (isStableIdentifier(resource)) {
168
172
  if (DEBUG) {
169
173
  // TODO should we instead just treat this case as a new generation skipping the short circuit?
170
- if (!(this._cache.lids[resource.lid] !== undefined) || this._cache.lids[resource.lid] !== resource) {
174
+ if (!this._cache.lids.has(resource.lid) || this._cache.lids.get(resource.lid) !== resource) {
171
175
  throw new Error(`The supplied identifier ${resource} does not belong to this store instance`);
172
176
  }
173
177
  }
@@ -179,7 +183,7 @@ export class IdentifierCache {
179
183
  }
180
184
 
181
185
  let lid = coerceId(resource.lid);
182
- let identifier: StableRecordIdentifier | undefined = lid !== null ? this._cache.lids[lid] : undefined;
186
+ let identifier: StableRecordIdentifier | undefined = lid !== null ? this._cache.lids.get(lid) : undefined;
183
187
 
184
188
  if (identifier !== undefined) {
185
189
  if (LOG_IDENTIFIERS) {
@@ -210,13 +214,13 @@ export class IdentifierCache {
210
214
 
211
215
  // go straight for the stable RecordIdentifier key'd to `lid`
212
216
  if (lid !== null) {
213
- identifier = keyOptions.lid[lid];
217
+ identifier = keyOptions.lid.get(lid);
214
218
  }
215
219
 
216
220
  // we may have not seen this resource before
217
221
  // but just in case we check our own secondary lookup (`id`)
218
222
  if (identifier === undefined && id !== null) {
219
- identifier = keyOptions.id[id];
223
+ identifier = keyOptions.id.get(id);
220
224
  }
221
225
 
222
226
  if (identifier === undefined) {
@@ -233,12 +237,12 @@ export class IdentifierCache {
233
237
  // different than expected
234
238
  if (lid !== null && newLid !== lid) {
235
239
  throw new Error(`You should not change the <lid> of a RecordIdentifier`);
236
- } else if (lid === null) {
240
+ } else if (lid === null && !this._isDefaultConfig) {
237
241
  // allow configuration to tell us that we have
238
242
  // seen this `lid` before. E.g. a secondary lookup
239
243
  // connects this resource to a previously seen
240
244
  // resource.
241
- identifier = keyOptions.lid[newLid];
245
+ identifier = keyOptions.lid.get(newLid);
242
246
  }
243
247
 
244
248
  if (shouldGenerate === true) {
@@ -250,16 +254,16 @@ export class IdentifierCache {
250
254
  if (DEBUG) {
251
255
  // realistically if you hit this it means you changed `type` :/
252
256
  // TODO consider how to handle type change assertions more gracefully
253
- if (this._cache.lids[identifier.lid] !== undefined) {
257
+ if (this._cache.lids.has(identifier.lid)) {
254
258
  throw new Error(`You should not change the <type> of a RecordIdentifier`);
255
259
  }
256
260
  }
257
- this._cache.lids[identifier.lid] = identifier;
261
+ this._cache.lids.set(identifier.lid, identifier);
258
262
 
259
263
  // populate our primary lookup table
260
264
  // TODO consider having the `lid` cache be
261
265
  // one level up
262
- keyOptions.lid[identifier.lid] = identifier;
266
+ keyOptions.lid.set(identifier.lid, identifier);
263
267
 
264
268
  if (LOG_IDENTIFIERS && shouldGenerate) {
265
269
  // eslint-disable-next-line no-console
@@ -281,7 +285,7 @@ export class IdentifierCache {
281
285
  // because they may not match and we prefer
282
286
  // what we've set via resource data
283
287
  if (identifier.id !== null) {
284
- keyOptions.id[identifier.id] = identifier;
288
+ keyOptions.id.set(identifier.id, identifier);
285
289
 
286
290
  // TODO allow filling out of `id` here
287
291
  // for the `username` non-client created
@@ -355,14 +359,17 @@ export class IdentifierCache {
355
359
 
356
360
  // populate our unique table
357
361
  if (DEBUG) {
358
- if (this._cache.lids[identifier.lid] !== undefined) {
362
+ if (this._cache.lids.has(identifier.lid)) {
359
363
  throw new Error(`The lid generated for the new record is not unique as it matches an existing identifier`);
360
364
  }
361
365
  }
362
- this._cache.lids[identifier.lid] = identifier;
366
+ this._cache.lids.set(identifier.lid, identifier);
363
367
 
364
368
  // populate the type+lid cache
365
- keyOptions.lid[newLid] = identifier;
369
+ keyOptions.lid.set(newLid, identifier);
370
+ if (data.id) {
371
+ keyOptions.id.set(data.id, identifier);
372
+ }
366
373
 
367
374
  if (LOG_IDENTIFIERS) {
368
375
  // eslint-disable-next-line no-console
@@ -448,10 +455,10 @@ export class IdentifierCache {
448
455
  );
449
456
  }
450
457
  let keyOptions = getTypeIndex(this._cache.types, identifier.type);
451
- keyOptions.id[newId] = identifier;
458
+ keyOptions.id.set(newId, identifier);
452
459
 
453
460
  if (id !== null) {
454
- keyOptions.id[id] = undefined as unknown as StableRecordIdentifier;
461
+ keyOptions.id.delete(id);
455
462
  }
456
463
  } else if (LOG_IDENTIFIERS) {
457
464
  // eslint-disable-next-line no-console
@@ -480,10 +487,10 @@ export class IdentifierCache {
480
487
  this.forgetRecordIdentifier(abandoned);
481
488
 
482
489
  // ensure a secondary cache entry for this id for the identifier we do keep
483
- keyOptions.id[newId] = kept;
490
+ keyOptions.id.set(newId, kept);
484
491
  // ensure a secondary cache entry for this id for the abandoned identifier's type we do keep
485
492
  let baseKeyOptions = getTypeIndex(this._cache.types, existingIdentifier.type);
486
- baseKeyOptions.id[newId] = kept;
493
+ baseKeyOptions.id.set(newId, kept);
487
494
 
488
495
  // make sure that the `lid` on the data we are processing matches the lid we kept
489
496
  data.lid = kept.lid;
@@ -507,10 +514,10 @@ export class IdentifierCache {
507
514
  let identifier = this.getOrCreateRecordIdentifier(identifierObject);
508
515
  let keyOptions = getTypeIndex(this._cache.types, identifier.type);
509
516
  if (identifier.id !== null) {
510
- keyOptions.id[identifier.id] = undefined as unknown as StableRecordIdentifier;
517
+ keyOptions.id.delete(identifier.id);
511
518
  }
512
- this._cache.lids[identifier.lid] = undefined as unknown as StableRecordIdentifier;
513
- keyOptions.lid[identifier.lid] = undefined as unknown as StableRecordIdentifier;
519
+ this._cache.lids.delete(identifier.lid);
520
+ keyOptions.lid.delete(identifier.lid);
514
521
 
515
522
  IDENTIFIERS.delete(identifierObject);
516
523
  this._forget(identifier, 'record');
@@ -530,8 +537,8 @@ function getTypeIndex(typeMap: TypeMap, type: string): KeyOptions {
530
537
 
531
538
  if (typeIndex === undefined) {
532
539
  typeIndex = {
533
- lid: Object.create(null),
534
- id: Object.create(null),
540
+ lid: new Map(),
541
+ id: new Map(),
535
542
  };
536
543
  typeMap[type] = typeIndex;
537
544
  }
@@ -650,7 +657,7 @@ function detectMerge(
650
657
  const { id, type, lid } = identifier;
651
658
  if (id !== null && id !== newId && newId !== null) {
652
659
  let keyOptions = getTypeIndex(typesCache, identifier.type);
653
- let existingIdentifier = keyOptions.id[newId];
660
+ let existingIdentifier = keyOptions.id.get(newId);
654
661
 
655
662
  return existingIdentifier !== undefined ? existingIdentifier : false;
656
663
  } else {
@@ -658,12 +665,12 @@ function detectMerge(
658
665
 
659
666
  // If the ids and type are the same but lid is not the same, we should trigger a merge of the identifiers
660
667
  if (id !== null && id === newId && newType === type && data.lid && data.lid !== lid) {
661
- let existingIdentifier = lids[data.lid];
668
+ let existingIdentifier = lids.get(data.lid);
662
669
  return existingIdentifier !== undefined ? existingIdentifier : false;
663
670
  // If the lids are the same, and ids are the same, but types are different we should trigger a merge of the identifiers
664
671
  } else if (id !== null && id === newId && newType && newType !== type && data.lid && data.lid === lid) {
665
672
  let keyOptions = getTypeIndex(typesCache, newType);
666
- let existingIdentifier = keyOptions.id[id];
673
+ let existingIdentifier = keyOptions.id.get(id);
667
674
  return existingIdentifier !== undefined ? existingIdentifier : false;
668
675
  }
669
676
  }
@@ -37,7 +37,6 @@ import { assertIdentifierHasId } from '../store-service';
37
37
  import coerceId, { ensureStringId } from '../utils/coerce-id';
38
38
  import constructResource from '../utils/construct-resource';
39
39
  import normalizeModelName from '../utils/normalize-model-name';
40
- import WeakCache, { DebugWeakCache } from '../utils/weak-cache';
41
40
  import { removeRecordDataFor, setRecordDataFor } from './record-data-for';
42
41
 
43
42
  let _peekGraph: peekGraph;
@@ -54,10 +53,7 @@ if (HAS_RECORD_DATA_PACKAGE) {
54
53
  @module @ember-data/store
55
54
  */
56
55
 
57
- const RecordCache = new WeakCache<RecordInstance, StableRecordIdentifier>(DEBUG ? 'identifier' : '');
58
- if (DEBUG) {
59
- RecordCache._expectMsg = (key: RecordInstance) => `${String(key)} is not a record instantiated by @ember-data/store`;
60
- }
56
+ const RecordCache = new Map<RecordInstance, StableRecordIdentifier>();
61
57
 
62
58
  export function peekRecordIdentifier(record: RecordInstance): StableRecordIdentifier | undefined {
63
59
  return RecordCache.get(record);
@@ -83,7 +79,8 @@ export function peekRecordIdentifier(record: RecordInstance): StableRecordIdenti
83
79
  @returns {StableRecordIdentifier}
84
80
  */
85
81
  export function recordIdentifierFor(record: RecordInstance): StableRecordIdentifier {
86
- return RecordCache.getWithError(record);
82
+ assert(`${String(record)} is not a record instantiated by @ember-data/store`, RecordCache.has(record));
83
+ return RecordCache.get(record)!;
87
84
  }
88
85
 
89
86
  export function setRecordIdentifier(record: RecordInstance, identifier: StableRecordIdentifier): void {
@@ -102,7 +99,7 @@ export function setRecordIdentifier(record: RecordInstance, identifier: StableRe
102
99
  RecordCache.set(record, identifier);
103
100
  }
104
101
 
105
- export const StoreMap = new WeakCache<RecordInstance, Store>(DEBUG ? 'store' : '');
102
+ export const StoreMap = new Map<RecordInstance, Store>();
106
103
 
107
104
  export function storeFor(record: RecordInstance): Store | undefined {
108
105
  const store = StoreMap.get(record);
@@ -117,33 +114,32 @@ export function storeFor(record: RecordInstance): Store | undefined {
117
114
  type Caches = {
118
115
  record: Map<StableRecordIdentifier, RecordInstance>;
119
116
  recordData: Map<StableRecordIdentifier, RecordData>;
120
- reference: DebugWeakCache<StableRecordIdentifier, RecordReference>;
117
+ reference: WeakMap<StableRecordIdentifier, RecordReference>;
121
118
  };
122
119
 
123
120
  export class InstanceCache {
124
121
  declare store: Store;
125
122
  declare _storeWrapper: RecordDataStoreWrapper;
126
- declare peekList: Dict<Set<StableRecordIdentifier>>;
127
123
  declare __recordDataFor: (resource: RecordIdentifier) => RecordData;
128
124
 
129
125
  declare __cacheManager: NonSingletonRecordDataManager;
130
126
  __instances: Caches = {
131
127
  record: new Map<StableRecordIdentifier, RecordInstance>(),
132
128
  recordData: new Map<StableRecordIdentifier, RecordData>(),
133
- reference: new WeakCache<StableRecordIdentifier, RecordReference>(DEBUG ? 'reference' : ''),
129
+ reference: new WeakMap<StableRecordIdentifier, RecordReference>(),
134
130
  };
135
131
 
136
132
  recordIsLoaded(identifier: StableRecordIdentifier, filterDeleted: boolean = false) {
137
- const recordData = this.peek({ identifier, bucket: 'recordData' });
133
+ const recordData = this.__instances.recordData.get(identifier);
138
134
  if (!recordData) {
139
135
  return false;
140
136
  }
141
137
  const isNew = recordData.isNew(identifier);
142
- const isEmpty = recordData.isEmpty?.(identifier) || false;
138
+ const isEmpty = recordData.isEmpty(identifier);
143
139
 
144
140
  // if we are new we must consider ourselves loaded
145
141
  if (isNew) {
146
- return true;
142
+ return !recordData.isDeleted(identifier);
147
143
  }
148
144
  // even if we have a past request, if we are now empty we are not loaded
149
145
  // typically this is true after an unloadRecord call
@@ -152,23 +148,27 @@ export class InstanceCache {
152
148
  // we should consider allowing for something to be loaded that is simply "not empty".
153
149
  // which is how RecordState currently handles this case; however, RecordState is buggy
154
150
  // in that it does not account for unloading.
155
- // return !isEmpty;
151
+ return filterDeleted && recordData.isDeletionCommitted(identifier) ? false : !isEmpty;
156
152
 
153
+ /*
157
154
  const req = this.store.getRequestStateService();
158
155
  const fulfilled = req.getLastRequestForRecord(identifier);
156
+ const isLocallyLoaded = !isEmpty;
159
157
  const isLoading =
160
- fulfilled !== null && req.getPendingRequestsForRecord(identifier).some((req) => req.type === 'query');
158
+ !isLocallyLoaded &&
159
+ fulfilled === null &&
160
+ req.getPendingRequestsForRecord(identifier).some((req) => req.type === 'query');
161
161
 
162
162
  if (isEmpty || (filterDeleted && recordData.isDeletionCommitted(identifier)) || isLoading) {
163
163
  return false;
164
164
  }
165
165
 
166
166
  return true;
167
+ */
167
168
  }
168
169
 
169
170
  constructor(store: Store) {
170
171
  this.store = store;
171
- this.peekList = Object.create(null) as Dict<Set<StableRecordIdentifier>>;
172
172
 
173
173
  this._storeWrapper = new RecordDataStoreWrapper(this.store);
174
174
  this.__recordDataFor = (resource: RecordIdentifier) => {
@@ -177,10 +177,6 @@ export class InstanceCache {
177
177
  return this.getRecordData(identifier);
178
178
  };
179
179
 
180
- this.__instances.reference._generator = (identifier) => {
181
- return new RecordReference(this.store, identifier);
182
- };
183
-
184
180
  store.identifierCache.__configureMerge(
185
181
  (identifier: StableRecordIdentifier, matchedIdentifier: StableRecordIdentifier, resourceData) => {
186
182
  let intendedIdentifier = identifier;
@@ -228,7 +224,6 @@ export class InstanceCache {
228
224
  // remove "other" from cache
229
225
  if (otherHasRecord) {
230
226
  // TODO probably need to release other things
231
- this.peekList[altIdentifier.type]?.delete(altIdentifier);
232
227
  }
233
228
 
234
229
  if (imRecordData === null && otherRecordData === null) {
@@ -244,14 +239,11 @@ export class InstanceCache {
244
239
  if (imRecordData) {
245
240
  // TODO check if we are retained in any async relationships
246
241
  // TODO probably need to release other things
247
- this.peekList[intendedIdentifier.type]?.delete(intendedIdentifier);
248
242
  // im.destroy();
249
243
  }
250
244
  imRecordData = otherRecordData!;
251
245
  // TODO do we need to notify the id change?
252
246
  // TODO swap recordIdentifierFor result?
253
- this.peekList[intendedIdentifier.type] = this.peekList[intendedIdentifier.type] || new Set();
254
- this.peekList[intendedIdentifier.type]!.add(intendedIdentifier);
255
247
 
256
248
  // just use im
257
249
  } else {
@@ -285,7 +277,7 @@ export class InstanceCache {
285
277
  }
286
278
 
287
279
  getRecord(identifier: StableRecordIdentifier, properties?: CreateRecordProperties): RecordInstance {
288
- let record = this.peek({ identifier, bucket: 'record' });
280
+ let record = this.__instances.record.get(identifier);
289
281
 
290
282
  if (!record) {
291
283
  const recordData = this.getRecordData(identifier);
@@ -311,7 +303,7 @@ export class InstanceCache {
311
303
  }
312
304
 
313
305
  getRecordData(identifier: StableRecordIdentifier): RecordData {
314
- let recordData = this.peek({ identifier, bucket: 'recordData' });
306
+ let recordData = this.__instances.recordData.get(identifier);
315
307
 
316
308
  if (!recordData) {
317
309
  if (DEPRECATE_V1CACHE_STORE_APIS && this.store.createRecordDataFor.length > 2) {
@@ -354,8 +346,6 @@ export class InstanceCache {
354
346
  setRecordDataFor(identifier, recordData);
355
347
 
356
348
  this.__instances.recordData.set(identifier, recordData);
357
- this.peekList[identifier.type] = this.peekList[identifier.type] || new Set();
358
- this.peekList[identifier.type]!.add(identifier);
359
349
  if (LOG_INSTANCE_CACHE) {
360
350
  // eslint-disable-next-line no-console
361
351
  console.log(`InstanceCache: created RecordData for ${String(identifier)}`);
@@ -366,7 +356,14 @@ export class InstanceCache {
366
356
  }
367
357
 
368
358
  getReference(identifier: StableRecordIdentifier) {
369
- return this.__instances.reference.lookup(identifier);
359
+ let cache = this.__instances.reference;
360
+ let reference = cache.get(identifier);
361
+
362
+ if (!reference) {
363
+ reference = new RecordReference(this.store, identifier);
364
+ cache.set(identifier, reference);
365
+ }
366
+ return reference;
370
367
  }
371
368
 
372
369
  createSnapshot(identifier: StableRecordIdentifier, options: FindOptions = {}): Snapshot {
@@ -411,10 +408,9 @@ export class InstanceCache {
411
408
  }
412
409
 
413
410
  // TODO is this join still necessary?
414
- this.store._backburner.join(() => {
415
- const record = this.peek({ identifier, bucket: 'record' });
416
- const recordData = this.peek({ identifier, bucket: 'recordData' });
417
- this.peekList[identifier.type]?.delete(identifier);
411
+ this.store._join(() => {
412
+ const record = this.__instances.record.get(identifier);
413
+ const recordData = this.__instances.recordData.get(identifier);
418
414
 
419
415
  if (record) {
420
416
  this.store.teardownRecord(record);
@@ -438,7 +434,7 @@ export class InstanceCache {
438
434
  }
439
435
 
440
436
  this.store._fetchManager.clearEntries(identifier);
441
- this.store.recordArrayManager.recordDidChange(identifier);
437
+ this.store.recordArrayManager.identifierRemoved(identifier);
442
438
  if (LOG_INSTANCE_CACHE) {
443
439
  // eslint-disable-next-line no-console
444
440
  console.log(`InstanceCache: unloaded RecordData for ${String(identifier)}`);
@@ -449,20 +445,19 @@ export class InstanceCache {
449
445
  }
450
446
 
451
447
  clear(type?: string) {
448
+ const typeCache = this.store.identifierCache._cache.types;
452
449
  if (type === undefined) {
453
- let keys = Object.keys(this.peekList);
454
- keys.forEach((key) => this.clear(key));
450
+ this.__instances.recordData.forEach((value, identifier) => {
451
+ this.unloadRecord(identifier);
452
+ });
455
453
  } else {
456
- let identifiers = this.peekList[type];
454
+ let identifiers = typeCache[type]?.lid;
455
+ const rds = this.__instances.recordData;
457
456
  if (identifiers) {
458
457
  identifiers.forEach((identifier) => {
459
- // TODO we rely on not removing the main cache
460
- // and only removing the peekList cache apparently.
461
- // we should figure out this duality and codify whatever
462
- // signal it is actually trying to give us.
463
- // this.cache.delete(identifier);
464
- this.peekList[identifier.type]!.delete(identifier);
465
- this.unloadRecord(identifier);
458
+ if (rds.has(identifier)) {
459
+ this.unloadRecord(identifier);
460
+ }
466
461
  // TODO we don't remove the identifier, should we?
467
462
  });
468
463
  }
@@ -479,7 +474,7 @@ export class InstanceCache {
479
474
  const isLoading = _isLoading(this, identifier);
480
475
 
481
476
  if (options.preload) {
482
- this.store._backburner.join(() => {
477
+ this.store._join(() => {
483
478
  preloadData(this.store, identifier, options.preload!);
484
479
  });
485
480
  }
@@ -589,7 +584,7 @@ export class InstanceCache {
589
584
  recordData.pushData(identifier, data, hasRecord);
590
585
 
591
586
  if (!isUpdate) {
592
- this.store.recordArrayManager.recordDidChange(identifier);
587
+ this.store.recordArrayManager.identifierAdded(identifier);
593
588
  }
594
589
 
595
590
  return identifier as StableExistingRecordIdentifier;
@@ -603,7 +598,7 @@ function _recordDataIsFullDeleted(identifier: StableRecordIdentifier, recordData
603
598
  }
604
599
 
605
600
  export function recordDataIsFullyDeleted(cache: InstanceCache, identifier: StableRecordIdentifier): boolean {
606
- let recordData = cache.peek({ identifier, bucket: 'recordData' });
601
+ let recordData = cache.__instances.recordData.get(identifier);
607
602
  return !recordData || _recordDataIsFullDeleted(identifier, recordData);
608
603
  }
609
604
 
@@ -678,13 +673,13 @@ function _convertPreloadRelationshipToJSON(
678
673
  }
679
674
 
680
675
  function _isEmpty(cache: InstanceCache, identifier: StableRecordIdentifier): boolean {
681
- const recordData = cache.peek({ identifier: identifier, bucket: 'recordData' });
676
+ const recordData = cache.__instances.recordData.get(identifier);
682
677
  if (!recordData) {
683
678
  return true;
684
679
  }
685
680
  const isNew = recordData.isNew(identifier);
686
681
  const isDeleted = recordData.isDeleted(identifier);
687
- const isEmpty = recordData.isEmpty?.(identifier) || false;
682
+ const isEmpty = recordData.isEmpty(identifier);
688
683
 
689
684
  return (!isNew || isDeleted) && isEmpty;
690
685
  }
@@ -1,20 +1,15 @@
1
1
  import { assert } from '@ember/debug';
2
- import { DEBUG } from '@glimmer/env';
3
2
 
4
3
  import type { StableRecordIdentifier } from '@ember-data/types/q/identifier';
5
4
  import type { RecordData } from '@ember-data/types/q/record-data';
6
5
  import type { RecordInstance } from '@ember-data/types/q/record-instance';
7
6
 
8
- import WeakCache from '../utils/weak-cache';
9
-
10
7
  /*
11
8
  * Returns the RecordData instance associated with a given
12
9
  * Model or Identifier
13
10
  */
14
11
 
15
- const RecordDataForIdentifierCache = new WeakCache<StableRecordIdentifier | RecordInstance, RecordData>(
16
- DEBUG ? 'recordData' : ''
17
- );
12
+ const RecordDataForIdentifierCache = new Map<StableRecordIdentifier | RecordInstance, RecordData>();
18
13
 
19
14
  export function setRecordDataFor(identifier: StableRecordIdentifier | RecordInstance, recordData: RecordData): void {
20
15
  assert(
@@ -53,4 +53,3 @@ export { default as SnapshotRecordArray } from './network/snapshot-record-array'
53
53
 
54
54
  // leaked for private use / test use, should investigate removing
55
55
  export { default as recordDataFor, removeRecordDataFor } from './caches/record-data-for';
56
- export { default as WeakCache } from './utils/weak-cache';
@@ -1,18 +1,20 @@
1
- import { DEBUG } from '@glimmer/env';
2
-
3
1
  import type { ModelSchema } from '@ember-data/types/q/ds-model';
4
2
  import type { AttributeSchema, RelationshipSchema } from '@ember-data/types/q/record-data-schemas';
5
3
  import type { Dict } from '@ember-data/types/q/utils';
6
4
 
7
5
  import type Store from '../store-service';
8
- import WeakCache from '../utils/weak-cache';
9
6
 
10
- const AvailableShims = new WeakCache<Store, Dict<ShimModelClass>>(DEBUG ? 'schema-shims' : '');
11
- AvailableShims._generator = () => {
12
- return Object.create(null) as Dict<ShimModelClass>;
13
- };
7
+ // if modelFor turns out to be a bottleneck we should replace with a Map
8
+ // and clear it during store teardown.
9
+ const AvailableShims = new WeakMap<Store, Dict<ShimModelClass>>();
10
+
14
11
  export function getShimClass(store: Store, modelName: string): ShimModelClass {
15
- let shims = AvailableShims.lookup(store);
12
+ let shims = AvailableShims.get(store);
13
+
14
+ if (!shims) {
15
+ shims = Object.create(null) as Dict<ShimModelClass>;
16
+ AvailableShims.set(store, shims);
17
+ }
16
18
  let shim = shims[modelName];
17
19
  if (shim === undefined) {
18
20
  shim = shims[modelName] = new ShimModelClass(store, modelName);