@ember-data/store 4.5.0-beta.0 → 4.5.0

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 (64) hide show
  1. package/addon/-private/{system/backburner.js → backburner.js} +0 -0
  2. package/addon/-private/{system/coerce-id.ts → coerce-id.ts} +0 -0
  3. package/addon/-private/{system/store/common.js → common.js} +0 -0
  4. package/addon/-private/{system/core-store.ts → core-store.ts} +467 -1253
  5. package/addon/-private/{system/errors-utils.js → errors-utils.js} +7 -6
  6. package/addon/-private/{system/fetch-manager.ts → fetch-manager.ts} +72 -42
  7. package/addon/-private/finders.js +107 -0
  8. package/addon/-private/identifer-debug-consts.ts +3 -0
  9. package/addon/-private/{identifiers/cache.ts → identifier-cache.ts} +26 -14
  10. package/addon/-private/{system/identity-map.ts → identity-map.ts} +2 -1
  11. package/addon/-private/index.ts +17 -17
  12. package/addon/-private/instance-cache.ts +387 -0
  13. package/addon/-private/{system/store/internal-model-factory.ts → internal-model-factory.ts} +25 -19
  14. package/addon/-private/{system/internal-model-map.ts → internal-model-map.ts} +9 -5
  15. package/addon/-private/model/internal-model.ts +602 -0
  16. package/addon/-private/{system/references/record.ts → model/record-reference.ts} +23 -36
  17. package/addon/-private/{system/model → model}/shim-model-class.ts +19 -14
  18. package/addon/-private/{system/normalize-model-name.ts → normalize-model-name.ts} +0 -0
  19. package/addon/-private/{system/promise-proxies.ts → promise-proxies.ts} +12 -5
  20. package/addon/-private/{system/promise-proxy-base.js → promise-proxy-base.js} +0 -0
  21. package/addon/-private/{system/record-array-manager.ts → record-array-manager.ts} +19 -18
  22. package/addon/-private/{system/record-arrays → record-arrays}/adapter-populated-record-array.ts +11 -10
  23. package/addon/-private/{system/record-arrays → record-arrays}/record-array.ts +37 -19
  24. package/addon/-private/record-data-for.ts +39 -0
  25. package/addon/-private/{system/store/record-data-store-wrapper.ts → record-data-store-wrapper.ts} +21 -26
  26. package/addon/-private/{system/record-notification-manager.ts → record-notification-manager.ts} +8 -3
  27. package/addon/-private/{system/request-cache.ts → request-cache.ts} +5 -6
  28. package/addon/-private/{system/schema-definition-service.ts → schema-definition-service.ts} +30 -14
  29. package/addon/-private/{system/store/serializer-response.ts → serializer-response.ts} +7 -6
  30. package/addon/-private/{system/snapshot-record-array.ts → snapshot-record-array.ts} +27 -8
  31. package/addon/-private/{system/snapshot.ts → snapshot.ts} +54 -39
  32. package/addon/-private/utils/construct-resource.ts +7 -3
  33. package/addon/-private/utils/promise-record.ts +9 -18
  34. package/addon/-private/{system/weak-cache.ts → weak-cache.ts} +2 -2
  35. package/addon/index.ts +1 -0
  36. package/package.json +21 -20
  37. package/addon/-private/identifiers/is-stable-identifier.ts +0 -18
  38. package/addon/-private/identifiers/utils/uuid-v4.ts +0 -80
  39. package/addon/-private/system/ds-model-store.ts +0 -136
  40. package/addon/-private/system/model/internal-model.ts +0 -1303
  41. package/addon/-private/system/model/states.js +0 -736
  42. package/addon/-private/system/record-arrays.ts +0 -8
  43. package/addon/-private/system/record-data-for.ts +0 -54
  44. package/addon/-private/system/references/belongs-to.ts +0 -406
  45. package/addon/-private/system/references/has-many.ts +0 -487
  46. package/addon/-private/system/references/reference.ts +0 -205
  47. package/addon/-private/system/references.js +0 -9
  48. package/addon/-private/system/store/finders.js +0 -412
  49. package/addon/-private/ts-interfaces/ds-model.ts +0 -50
  50. package/addon/-private/ts-interfaces/ember-data-json-api.ts +0 -145
  51. package/addon/-private/ts-interfaces/fetch-manager.ts +0 -44
  52. package/addon/-private/ts-interfaces/identifier.ts +0 -246
  53. package/addon/-private/ts-interfaces/minimum-adapter-interface.ts +0 -584
  54. package/addon/-private/ts-interfaces/minimum-serializer-interface.ts +0 -257
  55. package/addon/-private/ts-interfaces/promise-proxies.ts +0 -3
  56. package/addon/-private/ts-interfaces/record-data-json-api.ts +0 -29
  57. package/addon/-private/ts-interfaces/record-data-record-wrapper.ts +0 -46
  58. package/addon/-private/ts-interfaces/record-data-schemas.ts +0 -45
  59. package/addon/-private/ts-interfaces/record-data-store-wrapper.ts +0 -56
  60. package/addon/-private/ts-interfaces/record-data.ts +0 -72
  61. package/addon/-private/ts-interfaces/record-instance.ts +0 -18
  62. package/addon/-private/ts-interfaces/schema-definition-service.ts +0 -12
  63. package/addon/-private/ts-interfaces/store.ts +0 -10
  64. package/addon/-private/ts-interfaces/utils.ts +0 -6
@@ -1,6 +1,3 @@
1
- import { makeArray } from '@ember/array';
2
- import { isPresent } from '@ember/utils';
3
-
4
1
  /**
5
2
  @module @ember-data/adapter/error
6
3
  */
@@ -9,13 +6,17 @@ const SOURCE_POINTER_REGEXP = /^\/?data\/(attributes|relationships)\/(.*)/;
9
6
  const SOURCE_POINTER_PRIMARY_REGEXP = /^\/?data/;
10
7
  const PRIMARY_ATTRIBUTE_KEY = 'base';
11
8
 
9
+ function makeArray(value) {
10
+ return Array.isArray(value) ? value : [value];
11
+ }
12
+
12
13
  /**
13
14
  Convert an hash of errors into an array with errors in JSON-API format.
14
15
  ```javascript
15
16
  import DS from 'ember-data';
16
17
 
17
18
  const { errorsHashToArray } = DS;
18
-
19
+
19
20
  let errors = {
20
21
  base: 'Invalid attributes on saving this record',
21
22
  name: 'Must be present',
@@ -55,7 +56,7 @@ const PRIMARY_ATTRIBUTE_KEY = 'base';
55
56
  export function errorsHashToArray(errors) {
56
57
  let out = [];
57
58
 
58
- if (isPresent(errors)) {
59
+ if (errors) {
59
60
  Object.keys(errors).forEach((key) => {
60
61
  let messages = makeArray(errors[key]);
61
62
  for (let i = 0; i < messages.length; i++) {
@@ -122,7 +123,7 @@ export function errorsHashToArray(errors) {
122
123
  export function errorsArrayToHash(errors) {
123
124
  let out = {};
124
125
 
125
- if (isPresent(errors)) {
126
+ if (errors) {
126
127
  errors.forEach((error) => {
127
128
  if (error.source && error.source.pointer) {
128
129
  let key = error.source.pointer.match(SOURCE_POINTER_REGEXP);
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  * @module @ember-data/store
3
3
  */
4
- import { A } from '@ember/array';
5
4
  import { assert, deprecate, warn } from '@ember/debug';
6
5
  import { _backburner as emberBackburner } from '@ember/runloop';
7
6
  import { DEBUG } from '@glimmer/env';
@@ -9,22 +8,25 @@ import { DEBUG } from '@glimmer/env';
9
8
  import { default as RSVP, resolve } from 'rsvp';
10
9
 
11
10
  import { DEPRECATE_RSVP_PROMISE } from '@ember-data/private-build-infra/deprecations';
11
+ import type { CollectionResourceDocument, SingleResourceDocument } from '@ember-data/types/q/ember-data-json-api';
12
+ import type { FindRecordQuery, Request, SaveRecordMutation } from '@ember-data/types/q/fetch-manager';
13
+ import type {
14
+ RecordIdentifier,
15
+ StableExistingRecordIdentifier,
16
+ StableRecordIdentifier,
17
+ } from '@ember-data/types/q/identifier';
18
+ import type { MinimumSerializerInterface } from '@ember-data/types/q/minimum-serializer-interface';
19
+ import type { FindOptions } from '@ember-data/types/q/store';
20
+ import type { Dict } from '@ember-data/types/q/utils';
12
21
 
13
- import type { CollectionResourceDocument, SingleResourceDocument } from '../ts-interfaces/ember-data-json-api';
14
- import type { FindRecordQuery, Request, SaveRecordMutation } from '../ts-interfaces/fetch-manager';
15
- import type { ExistingRecordIdentifier, RecordIdentifier, StableRecordIdentifier } from '../ts-interfaces/identifier';
16
- import type { MinimumSerializerInterface } from '../ts-interfaces/minimum-serializer-interface';
17
- import { FindOptions } from '../ts-interfaces/store';
18
- import type { Dict } from '../ts-interfaces/utils';
19
22
  import coerceId from './coerce-id';
20
- import type CoreStore from './core-store';
23
+ import { _bind, _guard, _objectIsAlive, guardDestroyedStore } from './common';
24
+ import type Store from './core-store';
21
25
  import { errorsArrayToHash } from './errors-utils';
22
26
  import ShimModelClass from './model/shim-model-class';
23
- import RequestCache, { RequestPromise } from './request-cache';
24
- import type { PrivateSnapshot } from './snapshot';
27
+ import RequestCache from './request-cache';
28
+ import { normalizeResponseHelper } from './serializer-response';
25
29
  import Snapshot from './snapshot';
26
- import { _bind, _guard, _objectIsAlive, guardDestroyedStore } from './store/common';
27
- import { normalizeResponseHelper } from './store/serializer-response';
28
30
  import WeakCache from './weak-cache';
29
31
 
30
32
  function payloadIsNotBlank(adapterPayload): boolean {
@@ -37,7 +39,7 @@ function payloadIsNotBlank(adapterPayload): boolean {
37
39
 
38
40
  type AdapterErrors = Error & { errors?: string[]; isAdapterError?: true };
39
41
  type SerializerWithParseErrors = MinimumSerializerInterface & {
40
- extractErrors?(store: CoreStore, modelClass: ShimModelClass, error: AdapterErrors, recordId: string | null): any;
42
+ extractErrors?(store: Store, modelClass: ShimModelClass, error: AdapterErrors, recordId: string | null): any;
41
43
  };
42
44
 
43
45
  export const SaveOp: unique symbol = Symbol('SaveOp');
@@ -45,11 +47,12 @@ export const SaveOp: unique symbol = Symbol('SaveOp');
45
47
  export type FetchMutationOptions = FindOptions & { [SaveOp]: 'createRecord' | 'deleteRecord' | 'updateRecord' };
46
48
 
47
49
  interface PendingFetchItem {
48
- identifier: ExistingRecordIdentifier;
50
+ identifier: StableExistingRecordIdentifier;
49
51
  queryRequest: Request;
50
52
  resolver: RSVP.Deferred<any>;
51
- options: { [k: string]: unknown };
53
+ options: FindOptions;
52
54
  trace?: any;
55
+ promise: Promise<StableRecordIdentifier>;
53
56
  }
54
57
 
55
58
  interface PendingSaveItem {
@@ -74,7 +77,7 @@ export default class FetchManager {
74
77
  // fetches pending in the runloop, waiting to be coalesced
75
78
  declare _pendingFetch: Map<string, PendingFetchItem[]>;
76
79
 
77
- constructor(private _store: CoreStore) {
80
+ constructor(private _store: Store) {
78
81
  // used to keep track of all the find requests that need to be coalesced
79
82
  this._pendingFetch = new Map();
80
83
  this._pendingSave = [];
@@ -124,9 +127,7 @@ export default class FetchManager {
124
127
  let adapter = this._store.adapterFor(identifier.type);
125
128
  let operation = options[SaveOp];
126
129
 
127
- // TODO We have to cast due to our reliance on this private property
128
- // this will be refactored away once we change our pending API to be identifier based
129
- let internalModel = (snapshot as unknown as PrivateSnapshot)._internalModel;
130
+ let internalModel = snapshot._internalModel;
130
131
  let modelName = snapshot.modelName;
131
132
  let store = this._store;
132
133
  let modelClass = store.modelFor(modelName);
@@ -207,8 +208,9 @@ export default class FetchManager {
207
208
  }
208
209
  }
209
210
 
210
- scheduleFetch(identifier: ExistingRecordIdentifier, options: any, shouldTrace: boolean): Promise<any> {
211
+ scheduleFetch(identifier: StableExistingRecordIdentifier, options: FindOptions): Promise<StableRecordIdentifier> {
211
212
  // TODO Probably the store should pass in the query object
213
+ let shouldTrace = DEBUG && this._store.generateStackTracesForTrackedRequests;
212
214
 
213
215
  let query: FindRecordQuery = {
214
216
  op: 'findRecord',
@@ -220,26 +222,21 @@ export default class FetchManager {
220
222
  data: [query],
221
223
  };
222
224
 
223
- let pendingFetches = this._pendingFetch.get(identifier.type);
224
-
225
- // We already have a pending fetch for this
226
- if (pendingFetches) {
227
- let matchingPendingFetch = pendingFetches.filter((fetch) => fetch.identifier.id === identifier.id)[0];
228
- if (matchingPendingFetch) {
229
- return matchingPendingFetch.resolver.promise;
230
- }
225
+ let pendingFetch = this.getPendingFetch(identifier, options);
226
+ if (pendingFetch) {
227
+ return pendingFetch;
231
228
  }
232
229
 
233
230
  let id = identifier.id;
234
231
  let modelName = identifier.type;
235
232
 
236
- let resolver = RSVP.defer(`Fetching ${modelName}' with id: ${id}`);
233
+ let resolver = RSVP.defer<SingleResourceDocument>(`Fetching ${modelName}' with id: ${id}`);
237
234
  let pendingFetchItem: PendingFetchItem = {
238
235
  identifier,
239
236
  resolver,
240
237
  options,
241
238
  queryRequest,
242
- };
239
+ } as PendingFetchItem;
243
240
 
244
241
  if (DEBUG) {
245
242
  if (shouldTrace) {
@@ -259,7 +256,36 @@ export default class FetchManager {
259
256
  }
260
257
  }
261
258
 
262
- let promise = resolver.promise;
259
+ let resolverPromise = resolver.promise;
260
+
261
+ // TODO replace with some form of record state cache
262
+ const store = this._store;
263
+ const internalModel = store._instanceCache.getInternalModel(identifier);
264
+ const isLoading = !internalModel.isLoaded; // we don't use isLoading directly because we are the request
265
+
266
+ const promise = resolverPromise.then(
267
+ (payload) => {
268
+ // ensure that regardless of id returned we assign to the correct record
269
+ if (payload.data && !Array.isArray(payload.data)) {
270
+ payload.data.lid = identifier.lid;
271
+ }
272
+
273
+ // additional data received in the payload
274
+ // may result in the merging of identifiers (and thus records)
275
+ let potentiallyNewIm = store._push(payload);
276
+ if (potentiallyNewIm && !Array.isArray(potentiallyNewIm)) {
277
+ return potentiallyNewIm;
278
+ }
279
+
280
+ return identifier;
281
+ },
282
+ (error) => {
283
+ if (internalModel.isEmpty || isLoading) {
284
+ internalModel.unloadRecord();
285
+ }
286
+ throw error;
287
+ }
288
+ );
263
289
 
264
290
  if (this._pendingFetch.size === 0) {
265
291
  emberBackburner.schedule('actions', this, this.flushAllPendingFetches);
@@ -273,7 +299,8 @@ export default class FetchManager {
273
299
 
274
300
  (fetches.get(modelName) as PendingFetchItem[]).push(pendingFetchItem);
275
301
 
276
- this.requestCache.enqueue(promise, pendingFetchItem.queryRequest);
302
+ pendingFetchItem.promise = promise;
303
+ this.requestCache.enqueue(resolverPromise, pendingFetchItem.queryRequest);
277
304
  return promise;
278
305
  }
279
306
 
@@ -410,7 +437,7 @@ export default class FetchManager {
410
437
 
411
438
  _findMany(
412
439
  adapter: any,
413
- store: CoreStore,
440
+ store: Store,
414
441
  modelName: string,
415
442
  snapshots: Snapshot[],
416
443
  identifiers: RecordIdentifier[],
@@ -418,7 +445,7 @@ export default class FetchManager {
418
445
  ) {
419
446
  let modelClass = store.modelFor(modelName); // `adapter.findMany` gets the modelClass still
420
447
  let ids = snapshots.map((s) => s.id);
421
- let promise = adapter.findMany(store, modelClass, ids, A(snapshots));
448
+ let promise = adapter.findMany(store, modelClass, ids, snapshots);
422
449
  let label = `DS: Handle Adapter#findMany of '${modelName}'`;
423
450
 
424
451
  if (promise === undefined) {
@@ -483,7 +510,7 @@ export default class FetchManager {
483
510
  let identifiers = new Array(totalItems);
484
511
  let seeking: { [id: string]: PendingFetchItem } = Object.create(null);
485
512
 
486
- let optionsMap = new WeakCache<RecordIdentifier, Dict<unknown>>(DEBUG ? 'fetch-options' : '');
513
+ let optionsMap = new WeakCache<RecordIdentifier, FindOptions>(DEBUG ? 'fetch-options' : '');
487
514
 
488
515
  for (let i = 0; i < totalItems; i++) {
489
516
  let pendingItem = pendingFetchItems[i];
@@ -529,13 +556,15 @@ export default class FetchManager {
529
556
  }
530
557
  }
531
558
 
532
- getPendingFetch(identifier: StableRecordIdentifier, options) {
533
- let pendingRequests = this.requestCache.getPendingRequestsForRecord(identifier).filter((req) => {
534
- return req.type === 'query' && isSameRequest(options, req.request.data[0].options);
535
- });
559
+ getPendingFetch(identifier: StableRecordIdentifier, options: FindOptions) {
560
+ let pendingFetches = this._pendingFetch.get(identifier.type);
536
561
 
537
- if (pendingRequests.length > 0) {
538
- return pendingRequests[0][RequestPromise];
562
+ // We already have a pending fetch for this
563
+ if (pendingFetches) {
564
+ let matchingPendingFetch = pendingFetches.find((fetch) => fetch.identifier === identifier);
565
+ if (matchingPendingFetch && isSameRequest(options, matchingPendingFetch.options)) {
566
+ return matchingPendingFetch.promise;
567
+ }
539
568
  }
540
569
  }
541
570
 
@@ -562,6 +591,7 @@ function assertIsString(id: string | null): asserts id is string {
562
591
  }
563
592
 
564
593
  // this function helps resolve whether we have a pending request that we should use instead
565
- function isSameRequest(options: Dict<unknown> = {}, reqOptions: Dict<unknown> = {}) {
594
+ // TODO @runspired @needsTest removing this did not cause any test failures
595
+ function isSameRequest(options: FindOptions = {}, reqOptions: FindOptions = {}) {
566
596
  return options.include === reqOptions.include;
567
597
  }
@@ -0,0 +1,107 @@
1
+ import { assert } from '@ember/debug';
2
+
3
+ import { Promise } from 'rsvp';
4
+
5
+ import { guardDestroyedStore } from './common';
6
+ import { normalizeResponseHelper } from './serializer-response';
7
+
8
+ /**
9
+ @module @ember-data/store
10
+ */
11
+
12
+ function payloadIsNotBlank(adapterPayload) {
13
+ if (Array.isArray(adapterPayload)) {
14
+ return true;
15
+ } else {
16
+ return Object.keys(adapterPayload || {}).length;
17
+ }
18
+ }
19
+
20
+ export function _findAll(adapter, store, modelName, options) {
21
+ let modelClass = store.modelFor(modelName); // adapter.findAll depends on the class
22
+ let recordArray = store.peekAll(modelName);
23
+ let snapshotArray = recordArray._createSnapshot(options);
24
+ let promise = Promise.resolve().then(() => adapter.findAll(store, modelClass, null, snapshotArray));
25
+ let label = 'DS: Handle Adapter#findAll of ' + modelClass;
26
+
27
+ promise = guardDestroyedStore(promise, store, label);
28
+
29
+ return promise.then(
30
+ (adapterPayload) => {
31
+ assert(
32
+ `You made a 'findAll' request for '${modelName}' records, but the adapter's response did not have any data`,
33
+ payloadIsNotBlank(adapterPayload)
34
+ );
35
+ let serializer = store.serializerFor(modelName);
36
+ let payload = normalizeResponseHelper(serializer, store, modelClass, adapterPayload, null, 'findAll');
37
+
38
+ store._push(payload);
39
+ store.recordArrayManager._didUpdateAll(modelName);
40
+
41
+ return recordArray;
42
+ },
43
+ null,
44
+ 'DS: Extract payload of findAll ${modelName}'
45
+ );
46
+ }
47
+
48
+ export function _query(adapter, store, modelName, query, recordArray, options) {
49
+ let modelClass = store.modelFor(modelName); // adapter.query needs the class
50
+
51
+ recordArray = recordArray || store.recordArrayManager.createAdapterPopulatedRecordArray(modelName, query);
52
+ let promise = Promise.resolve().then(() => adapter.query(store, modelClass, query, recordArray, options));
53
+
54
+ let label = `DS: Handle Adapter#query of ${modelName}`;
55
+ promise = guardDestroyedStore(promise, store, label);
56
+
57
+ return promise.then(
58
+ (adapterPayload) => {
59
+ let serializer = store.serializerFor(modelName);
60
+ let payload = normalizeResponseHelper(serializer, store, modelClass, adapterPayload, null, 'query');
61
+ let identifiers = store._push(payload);
62
+
63
+ assert(
64
+ 'The response to store.query is expected to be an array but it was a single record. Please wrap your response in an array or use `store.queryRecord` to query for a single record.',
65
+ Array.isArray(identifiers)
66
+ );
67
+ if (recordArray) {
68
+ recordArray._setIdentifiers(identifiers, payload);
69
+ } else {
70
+ recordArray = store.recordArrayManager.createAdapterPopulatedRecordArray(
71
+ modelName,
72
+ query,
73
+ identifiers,
74
+ payload
75
+ );
76
+ }
77
+
78
+ return recordArray;
79
+ },
80
+ null,
81
+ `DS: Extract payload of query ${modelName}`
82
+ );
83
+ }
84
+
85
+ export function _queryRecord(adapter, store, modelName, query, options) {
86
+ let modelClass = store.modelFor(modelName); // adapter.queryRecord needs the class
87
+ let promise = Promise.resolve().then(() => adapter.queryRecord(store, modelClass, query, options));
88
+
89
+ let label = `DS: Handle Adapter#queryRecord of ${modelName}`;
90
+ promise = guardDestroyedStore(promise, store, label);
91
+
92
+ return promise.then(
93
+ (adapterPayload) => {
94
+ let serializer = store.serializerFor(modelName);
95
+ let payload = normalizeResponseHelper(serializer, store, modelClass, adapterPayload, null, 'queryRecord');
96
+
97
+ assert(
98
+ `Expected the primary data returned by the serializer for a 'queryRecord' response to be a single object or null but instead it was an array.`,
99
+ !Array.isArray(payload.data)
100
+ );
101
+
102
+ return store._push(payload);
103
+ },
104
+ null,
105
+ `DS: Extract payload of queryRecord ${modelName}`
106
+ );
107
+ }
@@ -0,0 +1,3 @@
1
+ // provided for additional debuggability
2
+ export const DEBUG_CLIENT_ORIGINATED: unique symbol = Symbol('record-originated-on-client');
3
+ export const DEBUG_IDENTIFIER_BUCKET: unique symbol = Symbol('identifier-bucket');
@@ -4,10 +4,7 @@
4
4
  import { assert, warn } from '@ember/debug';
5
5
  import { DEBUG } from '@glimmer/env';
6
6
 
7
- import coerceId from '../system/coerce-id';
8
- import normalizeModelName from '../system/normalize-model-name';
9
- import WeakCache from '../system/weak-cache';
10
- import type { ExistingResourceObject, ResourceIdentifierObject } from '../ts-interfaces/ember-data-json-api';
7
+ import type { ExistingResourceObject, ResourceIdentifierObject } from '@ember-data/types/q/ember-data-json-api';
11
8
  import type {
12
9
  ForgetMethod,
13
10
  GenerationMethod,
@@ -18,12 +15,27 @@ import type {
18
15
  ResourceData,
19
16
  StableRecordIdentifier,
20
17
  UpdateMethod,
21
- } from '../ts-interfaces/identifier';
22
- import { DEBUG_CLIENT_ORIGINATED, DEBUG_IDENTIFIER_BUCKET } from '../ts-interfaces/identifier';
23
- import type { ConfidentDict } from '../ts-interfaces/utils';
24
- import isNonEmptyString from '../utils/is-non-empty-string';
25
- import isStableIdentifier, { markStableIdentifier, unmarkStableIdentifier } from './is-stable-identifier';
26
- import uuidv4 from './utils/uuid-v4';
18
+ } from '@ember-data/types/q/identifier';
19
+ import type { ConfidentDict } from '@ember-data/types/q/utils';
20
+
21
+ import coerceId from './coerce-id';
22
+ import { DEBUG_CLIENT_ORIGINATED, DEBUG_IDENTIFIER_BUCKET } from './identifer-debug-consts';
23
+ import normalizeModelName from './normalize-model-name';
24
+ import isNonEmptyString from './utils/is-non-empty-string';
25
+ import WeakCache from './weak-cache';
26
+
27
+ const IDENTIFIERS = new WeakSet();
28
+
29
+ export function isStableIdentifier(identifier: Object): identifier is StableRecordIdentifier {
30
+ return IDENTIFIERS.has(identifier);
31
+ }
32
+
33
+ const isFastBoot = typeof FastBoot !== 'undefined';
34
+ const _crypto: Crypto = isFastBoot ? (FastBoot.require('crypto') as Crypto) : window.crypto;
35
+
36
+ function uuidv4(): string {
37
+ return _crypto.randomUUID();
38
+ }
27
39
 
28
40
  function freeze<T>(obj: T): T {
29
41
  if (typeof Object.freeze === 'function') {
@@ -75,7 +87,7 @@ function defaultGenerationMethod(data: ResourceData | { type: string }, bucket:
75
87
  let { type, id } = data;
76
88
  // TODO: add test for id not a string
77
89
  if (isNonEmptyString(coerceId(id))) {
78
- return `@ember-data:lid-${normalizeModelName(type)}-${id}`;
90
+ return `@lid:${normalizeModelName(type)}-${id}`;
79
91
  }
80
92
  }
81
93
  return uuidv4();
@@ -440,7 +452,7 @@ export class IdentifierCache {
440
452
  let index = keyOptions._allIdentifiers.indexOf(identifier);
441
453
  keyOptions._allIdentifiers.splice(index, 1);
442
454
 
443
- unmarkStableIdentifier(identifierObject);
455
+ IDENTIFIERS.delete(identifierObject);
444
456
  this._forget(identifier, 'record');
445
457
  }
446
458
 
@@ -476,7 +488,7 @@ function makeStableRecordIdentifier(
476
488
  id,
477
489
  type,
478
490
  };
479
- markStableIdentifier(recordIdentifier);
491
+ IDENTIFIERS.add(recordIdentifier);
480
492
 
481
493
  if (DEBUG) {
482
494
  // we enforce immutability in dev
@@ -498,7 +510,7 @@ function makeStableRecordIdentifier(
498
510
  };
499
511
  wrapper[DEBUG_CLIENT_ORIGINATED] = clientOriginated;
500
512
  wrapper[DEBUG_IDENTIFIER_BUCKET] = bucket;
501
- markStableIdentifier(wrapper);
513
+ IDENTIFIERS.add(wrapper);
502
514
  DEBUG_MAP.set(wrapper, recordIdentifier);
503
515
  wrapper = freeze(wrapper);
504
516
  return wrapper;
@@ -1,4 +1,5 @@
1
- import type { ConfidentDict } from '../ts-interfaces/utils';
1
+ import type { ConfidentDict } from '@ember-data/types/q/utils';
2
+
2
3
  import InternalModelMap from './internal-model-map';
3
4
 
4
5
  /**
@@ -2,38 +2,38 @@
2
2
  @module @ember-data/store
3
3
  */
4
4
 
5
- export { default as Store } from './system/ds-model-store';
5
+ export { default as Store, storeFor } from './core-store';
6
6
 
7
- export { recordIdentifierFor } from './system/store/internal-model-factory';
7
+ export { recordIdentifierFor } from './internal-model-factory';
8
8
 
9
- export { default as Snapshot } from './system/snapshot';
9
+ export { default as Snapshot } from './snapshot';
10
10
  export {
11
11
  setIdentifierGenerationMethod,
12
12
  setIdentifierUpdateMethod,
13
13
  setIdentifierForgetMethod,
14
14
  setIdentifierResetMethod,
15
- } from './identifiers/cache';
15
+ } from './identifier-cache';
16
16
 
17
- export { default as normalizeModelName } from './system/normalize-model-name';
18
- export { default as coerceId } from './system/coerce-id';
17
+ export { default as normalizeModelName } from './normalize-model-name';
18
+ export { default as coerceId } from './coerce-id';
19
19
 
20
- export { errorsHashToArray, errorsArrayToHash } from './system/errors-utils';
20
+ export { errorsHashToArray, errorsArrayToHash } from './errors-utils';
21
21
 
22
- // `ember-data-model-fragments` relies on `RootState` and `InternalModel`
23
- export { default as RootState } from './system/model/states';
24
- export { default as InternalModel } from './system/model/internal-model';
22
+ // `ember-data-model-fragments` relies on `InternalModel`
23
+ export { default as InternalModel } from './model/internal-model';
25
24
 
26
- export { PromiseArray, PromiseObject, deprecatedPromiseObject } from './system/promise-proxies';
25
+ export { PromiseArray, PromiseObject, deprecatedPromiseObject } from './promise-proxies';
27
26
 
28
- export { RecordArray, AdapterPopulatedRecordArray } from './system/record-arrays';
27
+ export { default as RecordArray } from './record-arrays/record-array';
28
+ export { default as AdapterPopulatedRecordArray } from './record-arrays/adapter-populated-record-array';
29
29
 
30
- export { default as RecordArrayManager } from './system/record-array-manager';
30
+ export { default as RecordArrayManager } from './record-array-manager';
31
31
 
32
32
  // // Used by tests
33
- export { default as SnapshotRecordArray } from './system/snapshot-record-array';
33
+ export { default as SnapshotRecordArray } from './snapshot-record-array';
34
34
 
35
35
  // New
36
- export { default as recordDataFor, removeRecordDataFor } from './system/record-data-for';
37
- export { default as RecordDataStoreWrapper } from './system/store/record-data-store-wrapper';
36
+ export { default as recordDataFor, removeRecordDataFor } from './record-data-for';
37
+ export { default as RecordDataStoreWrapper } from './record-data-store-wrapper';
38
38
 
39
- export { default as WeakCache } from './system/weak-cache';
39
+ export { default as WeakCache } from './weak-cache';