@ember-data/store 4.6.1 → 4.7.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 (45) hide show
  1. package/addon/-debug/index.js +35 -13
  2. package/addon/-private/{identifier-cache.ts → caches/identifier-cache.ts} +148 -73
  3. package/addon/-private/caches/instance-cache.ts +690 -0
  4. package/addon/-private/{record-data-for.ts → caches/record-data-for.ts} +2 -7
  5. package/addon/-private/index.ts +44 -24
  6. package/addon/-private/{model → legacy-model-support}/record-reference.ts +15 -13
  7. package/addon/-private/{schema-definition-service.ts → legacy-model-support/schema-definition-service.ts} +13 -9
  8. package/addon/-private/{model → legacy-model-support}/shim-model-class.ts +18 -11
  9. package/addon/-private/managers/record-array-manager.ts +377 -0
  10. package/addon/-private/managers/record-data-manager.ts +845 -0
  11. package/addon/-private/managers/record-data-store-wrapper.ts +421 -0
  12. package/addon/-private/managers/record-notification-manager.ts +109 -0
  13. package/addon/-private/network/fetch-manager.ts +567 -0
  14. package/addon/-private/{finders.js → network/finders.js} +14 -17
  15. package/addon/-private/{request-cache.ts → network/request-cache.ts} +21 -18
  16. package/addon/-private/{snapshot-record-array.ts → network/snapshot-record-array.ts} +14 -31
  17. package/addon/-private/{snapshot.ts → network/snapshot.ts} +40 -49
  18. package/addon/-private/{promise-proxies.ts → proxies/promise-proxies.ts} +76 -15
  19. package/addon/-private/{promise-proxy-base.js → proxies/promise-proxy-base.js} +0 -0
  20. package/addon/-private/record-arrays/identifier-array.ts +924 -0
  21. package/addon/-private/{core-store.ts → store-service.ts} +574 -215
  22. package/addon/-private/{coerce-id.ts → utils/coerce-id.ts} +1 -1
  23. package/addon/-private/{common.js → utils/common.js} +1 -2
  24. package/addon/-private/utils/construct-resource.ts +2 -2
  25. package/addon/-private/{identifer-debug-consts.ts → utils/identifer-debug-consts.ts} +0 -0
  26. package/addon/-private/utils/is-non-empty-string.ts +1 -1
  27. package/addon/-private/{normalize-model-name.ts → utils/normalize-model-name.ts} +1 -3
  28. package/addon/-private/utils/promise-record.ts +5 -6
  29. package/addon/-private/{serializer-response.ts → utils/serializer-response.ts} +2 -2
  30. package/addon/-private/utils/uuid-polyfill.ts +73 -0
  31. package/package.json +12 -8
  32. package/addon/-private/backburner.js +0 -25
  33. package/addon/-private/errors-utils.js +0 -146
  34. package/addon/-private/fetch-manager.ts +0 -597
  35. package/addon/-private/identity-map.ts +0 -54
  36. package/addon/-private/instance-cache.ts +0 -387
  37. package/addon/-private/internal-model-factory.ts +0 -359
  38. package/addon/-private/internal-model-map.ts +0 -121
  39. package/addon/-private/model/internal-model.ts +0 -602
  40. package/addon/-private/record-array-manager.ts +0 -444
  41. package/addon/-private/record-arrays/adapter-populated-record-array.ts +0 -130
  42. package/addon/-private/record-arrays/record-array.ts +0 -318
  43. package/addon/-private/record-data-store-wrapper.ts +0 -243
  44. package/addon/-private/record-notification-manager.ts +0 -73
  45. package/addon/-private/weak-cache.ts +0 -125
@@ -5,7 +5,7 @@ import type {
5
5
  RequestState,
6
6
  SaveRecordMutation,
7
7
  } from '@ember-data/types/q/fetch-manager';
8
- import type { RecordIdentifier } from '@ember-data/types/q/identifier';
8
+ import type { RecordIdentifier, StableRecordIdentifier } from '@ember-data/types/q/identifier';
9
9
 
10
10
  const Touching: unique symbol = Symbol('touching');
11
11
  export const RequestPromise: unique symbol = Symbol('promise');
@@ -23,7 +23,7 @@ function hasRecordIdentifier(op: Operation): op is RecordOperation {
23
23
 
24
24
  export default class RequestCache {
25
25
  _pending: { [lid: string]: InternalRequest[] } = Object.create(null);
26
- _done: { [lid: string]: InternalRequest[] } = Object.create(null);
26
+ _done: Map<StableRecordIdentifier, InternalRequest[]> = new Map();
27
27
  _subscriptions: { [lid: string]: Function[] } = Object.create(null);
28
28
 
29
29
  enqueue(promise: Promise<any>, queryRequest: Request) {
@@ -62,7 +62,7 @@ export default class RequestCache {
62
62
  state: 'rejected',
63
63
  request: queryRequest,
64
64
  type,
65
- response: { data: error && error.error },
65
+ response: { data: error },
66
66
  } as InternalRequest;
67
67
  finalizedRequest[Touching] = request[Touching];
68
68
  this._addDone(finalizedRequest);
@@ -86,22 +86,25 @@ export default class RequestCache {
86
86
 
87
87
  _addDone(request: InternalRequest) {
88
88
  request[Touching].forEach((identifier) => {
89
- if (!this._done[identifier.lid]) {
90
- this._done[identifier.lid] = [];
91
- }
92
89
  // TODO add support for multiple
93
90
  let requestDataOp = request.request.data[0].op;
94
- this._done[identifier.lid] = this._done[identifier.lid].filter((req) => {
95
- // TODO add support for multiple
96
- let data;
97
- if (req.request.data instanceof Array) {
98
- data = req.request.data[0];
99
- } else {
100
- data = req.request.data;
101
- }
102
- return data.op !== requestDataOp;
103
- });
104
- this._done[identifier.lid].push(request);
91
+ let requests = this._done.get(identifier);
92
+
93
+ if (requests) {
94
+ requests = requests.filter((req) => {
95
+ // TODO add support for multiple
96
+ let data;
97
+ if (req.request.data instanceof Array) {
98
+ data = req.request.data[0];
99
+ } else {
100
+ data = req.request.data;
101
+ }
102
+ return data.op !== requestDataOp;
103
+ });
104
+ }
105
+ requests = requests || [];
106
+ requests.push(request);
107
+ this._done.set(identifier, requests);
105
108
  });
106
109
  }
107
110
 
@@ -120,7 +123,7 @@ export default class RequestCache {
120
123
  }
121
124
 
122
125
  getLastRequestForRecord(identifier: RecordIdentifier): RequestState | null {
123
- let requests = this._done[identifier.lid];
126
+ let requests = this._done.get(identifier);
124
127
  if (requests) {
125
128
  return requests[requests.length - 1];
126
129
  }
@@ -6,10 +6,13 @@ import { deprecate } from '@ember/debug';
6
6
 
7
7
  import { DEPRECATE_SNAPSHOT_MODEL_CLASS_ACCESS } from '@ember-data/private-build-infra/deprecations';
8
8
  import type { ModelSchema } from '@ember-data/types/q/ds-model';
9
+ import { StableRecordIdentifier } from '@ember-data/types/q/identifier';
9
10
  import type { FindOptions } from '@ember-data/types/q/store';
10
11
  import type { Dict } from '@ember-data/types/q/utils';
11
12
 
12
- import type RecordArray from './record-arrays/record-array';
13
+ import type IdentifierArray from '../record-arrays/identifier-array';
14
+ import { SOURCE } from '../record-arrays/identifier-array';
15
+ import Store from '../store-service';
13
16
  import type Snapshot from './snapshot';
14
17
  /**
15
18
  SnapshotRecordArray is not directly instantiable.
@@ -21,11 +24,11 @@ import type Snapshot from './snapshot';
21
24
  */
22
25
  export default class SnapshotRecordArray {
23
26
  declare _snapshots: Snapshot[] | null;
24
- declare _recordArray: RecordArray;
27
+ declare _recordArray: IdentifierArray;
25
28
  declare _type: ModelSchema | null;
29
+ declare __store: Store;
26
30
 
27
31
  declare length: number;
28
- declare meta: Dict<unknown> | null;
29
32
  declare adapterOptions?: Dict<unknown>;
30
33
  declare include?: string;
31
34
 
@@ -38,10 +41,10 @@ export default class SnapshotRecordArray {
38
41
  @private
39
42
  @constructor
40
43
  @param {RecordArray} recordArray
41
- @param {Object} meta
42
44
  @param options
43
45
  */
44
- constructor(recordArray: RecordArray, meta: Dict<unknown> | null, options: FindOptions = {}) {
46
+ constructor(store: Store, recordArray: IdentifierArray, options: FindOptions = {}) {
47
+ this.__store = store;
45
48
  /**
46
49
  An array of snapshots
47
50
  @private
@@ -77,30 +80,7 @@ export default class SnapshotRecordArray {
77
80
  @public
78
81
  @type {Number}
79
82
  */
80
- this.length = recordArray.get('length');
81
-
82
- /**
83
- Meta objects for the record array.
84
-
85
- Example
86
-
87
- ```app/adapters/post.js
88
- import JSONAPIAdapter from '@ember-data/adapter/json-api';
89
-
90
- export default class PostAdapter extends JSONAPIAdapter {
91
- shouldReloadAll(store, snapshotRecordArray) {
92
- let lastRequestTime = snapshotRecordArray.meta.lastRequestTime;
93
- let twentyMinutes = 20 * 60 * 1000;
94
- return Date.now() > lastRequestTime + twentyMinutes;
95
- }
96
- });
97
- ```
98
-
99
- @property meta
100
- @public
101
- @type {Object}
102
- */
103
- this.meta = meta;
83
+ this.length = recordArray.length as unknown as number; // deal with computedProperty shennanigans
104
84
 
105
85
  /**
106
86
  A hash of adapter options passed into the store method for this request.
@@ -201,7 +181,10 @@ export default class SnapshotRecordArray {
201
181
  return this._snapshots;
202
182
  }
203
183
 
204
- this._snapshots = this._recordArray._takeSnapshot();
184
+ const { _instanceCache } = this.__store;
185
+ this._snapshots = this._recordArray[SOURCE].map((identifier: StableRecordIdentifier) =>
186
+ _instanceCache.createSnapshot(identifier)
187
+ );
205
188
 
206
189
  return this._snapshots;
207
190
  }
@@ -220,7 +203,7 @@ if (DEPRECATE_SNAPSHOT_MODEL_CLASS_ACCESS) {
220
203
  since: { available: '4.5.0', enabled: '4.5.0' },
221
204
  }
222
205
  );
223
- return this._recordArray.get('type');
206
+ return this._recordArray.type;
224
207
  },
225
208
  });
226
209
  }
@@ -2,7 +2,6 @@
2
2
  @module @ember-data/store
3
3
  */
4
4
  import { assert, deprecate } from '@ember/debug';
5
- import { get } from '@ember/object';
6
5
 
7
6
  import { importSync } from '@embroider/macros';
8
7
 
@@ -10,11 +9,6 @@ import { HAS_RECORD_DATA_PACKAGE } from '@ember-data/private-build-infra';
10
9
  import { DEPRECATE_SNAPSHOT_MODEL_CLASS_ACCESS } from '@ember-data/private-build-infra/deprecations';
11
10
  import type BelongsToRelationship from '@ember-data/record-data/addon/-private/relationships/state/belongs-to';
12
11
  import type ManyRelationship from '@ember-data/record-data/addon/-private/relationships/state/has-many';
13
- import type { DSModel, DSModelSchema, ModelSchema } from '@ember-data/types/q/ds-model';
14
- import type {
15
- ExistingResourceIdentifierObject,
16
- NewResourceIdentifierObject,
17
- } from '@ember-data/types/q/ember-data-json-api';
18
12
  import type { StableRecordIdentifier } from '@ember-data/types/q/identifier';
19
13
  import type { OptionsHash } from '@ember-data/types/q/minimum-serializer-interface';
20
14
  import type { ChangedAttributesHash } from '@ember-data/types/q/record-data';
@@ -23,15 +17,10 @@ import type { RecordInstance } from '@ember-data/types/q/record-instance';
23
17
  import type { FindOptions } from '@ember-data/types/q/store';
24
18
  import type { Dict } from '@ember-data/types/q/utils';
25
19
 
26
- import type Store from './core-store';
27
- import type InternalModel from './model/internal-model';
20
+ import type Store from '../store-service';
28
21
 
29
22
  type RecordId = string | null;
30
23
 
31
- function schemaIsDSModel(schema: ModelSchema | DSModelSchema): schema is DSModelSchema {
32
- return (schema as DSModelSchema).isModel === true;
33
- }
34
-
35
24
  /**
36
25
  Snapshot is not directly instantiable.
37
26
  Instances are provided to a consuming application's
@@ -41,12 +30,11 @@ function schemaIsDSModel(schema: ModelSchema | DSModelSchema): schema is DSModel
41
30
  @public
42
31
  */
43
32
  export default class Snapshot implements Snapshot {
44
- private __attributes: Dict<unknown> | null = null;
45
- private _belongsToRelationships: Dict<Snapshot> = Object.create(null);
46
- private _belongsToIds: Dict<RecordId> = Object.create(null);
47
- private _hasManyRelationships: Dict<Snapshot[]> = Object.create(null);
48
- private _hasManyIds: Dict<RecordId[]> = Object.create(null);
49
- declare _internalModel: InternalModel;
33
+ declare __attributes: Dict<unknown> | null;
34
+ declare _belongsToRelationships: Dict<Snapshot>;
35
+ declare _belongsToIds: Dict<RecordId>;
36
+ declare _hasManyRelationships: Dict<Snapshot[]>;
37
+ declare _hasManyIds: Dict<RecordId[]>;
50
38
  declare _changedAttributes: ChangedAttributesHash;
51
39
 
52
40
  declare identifier: StableRecordIdentifier;
@@ -54,6 +42,7 @@ export default class Snapshot implements Snapshot {
54
42
  declare id: string | null;
55
43
  declare include?: unknown;
56
44
  declare adapterOptions?: Dict<unknown>;
45
+ declare _store: Store;
57
46
 
58
47
  /**
59
48
  * @method constructor
@@ -63,8 +52,16 @@ export default class Snapshot implements Snapshot {
63
52
  * @param identifier
64
53
  * @param _store
65
54
  */
66
- constructor(options: FindOptions, identifier: StableRecordIdentifier, private _store: Store) {
67
- let internalModel = (this._internalModel = _store._instanceCache._internalModelForResource(identifier));
55
+ constructor(options: FindOptions, identifier: StableRecordIdentifier, store: Store) {
56
+ this._store = store;
57
+
58
+ this.__attributes = null;
59
+ this._belongsToRelationships = Object.create(null);
60
+ this._belongsToIds = Object.create(null);
61
+ this._hasManyRelationships = Object.create(null);
62
+ this._hasManyIds = Object.create(null);
63
+
64
+ const hasRecord = !!store._instanceCache.peek({ identifier, bucket: 'record' });
68
65
  this.modelName = identifier.type;
69
66
 
70
67
  /**
@@ -83,7 +80,7 @@ export default class Snapshot implements Snapshot {
83
80
  in time" in which a snapshot is created, we greedily grab
84
81
  the values.
85
82
  */
86
- if (internalModel.hasRecord) {
83
+ if (hasRecord) {
87
84
  this._attributes;
88
85
  }
89
86
 
@@ -129,8 +126,8 @@ export default class Snapshot implements Snapshot {
129
126
  @public
130
127
  */
131
128
  this.modelName = identifier.type;
132
- if (internalModel.hasRecord) {
133
- this._changedAttributes = this._store._instanceCache.getRecordData(identifier).changedAttributes();
129
+ if (hasRecord) {
130
+ this._changedAttributes = this._store._instanceCache.getRecordData(identifier).changedAttrs(identifier);
134
131
  }
135
132
  }
136
133
 
@@ -156,17 +153,13 @@ export default class Snapshot implements Snapshot {
156
153
  if (this.__attributes !== null) {
157
154
  return this.__attributes;
158
155
  }
159
- let record = this.record;
160
156
  let attributes = (this.__attributes = Object.create(null));
161
- let attrs = Object.keys(this._store.getSchemaDefinitionService().attributesDefinitionFor(this.identifier));
162
- let recordData = this._store._instanceCache.getRecordData(this.identifier);
157
+ const { identifier } = this;
158
+ let attrs = Object.keys(this._store.getSchemaDefinitionService().attributesDefinitionFor(identifier));
159
+ let recordData = this._store._instanceCache.getRecordData(identifier);
160
+
163
161
  attrs.forEach((keyName) => {
164
- if (schemaIsDSModel(this._internalModel.modelClass)) {
165
- // if the schema is for a DSModel then the instance is too
166
- attributes[keyName] = get(record as DSModel, keyName);
167
- } else {
168
- attributes[keyName] = recordData.getAttr(keyName);
169
- }
162
+ attributes[keyName] = recordData.getAttr(identifier, keyName);
170
163
  });
171
164
 
172
165
  return attributes;
@@ -182,7 +175,8 @@ export default class Snapshot implements Snapshot {
182
175
  */
183
176
 
184
177
  get isNew(): boolean {
185
- return this._internalModel.isNew();
178
+ const recordData = this._store._instanceCache.peek({ identifier: this.identifier, bucket: 'recordData' });
179
+ return recordData?.isNew(this.identifier) || false;
186
180
  }
187
181
 
188
182
  /**
@@ -297,9 +291,8 @@ export default class Snapshot implements Snapshot {
297
291
  */
298
292
  belongsTo(keyName: string, options?: { id?: boolean }): Snapshot | RecordId | undefined {
299
293
  let returnModeIsId = !!(options && options.id);
300
- let inverseInternalModel: InternalModel | null;
301
294
  let result: Snapshot | RecordId | undefined;
302
- let store = this._internalModel.store;
295
+ let store = this._store;
303
296
 
304
297
  if (returnModeIsId === true && keyName in this._belongsToIds) {
305
298
  return this._belongsToIds[keyName];
@@ -319,7 +312,7 @@ export default class Snapshot implements Snapshot {
319
312
 
320
313
  // TODO @runspired it seems this code branch would not work with CUSTOM_MODEL_CLASSes
321
314
  // this check is not a regression in behavior because relationships don't currently
322
- // function without access to intimate API contracts between RecordData and InternalModel.
315
+ // function without access to intimate API contracts between RecordData and Model.
323
316
  // This is a requirement we should fix as soon as the relationship layer does not require
324
317
  // this intimate API usage.
325
318
  if (!HAS_RECORD_DATA_PACKAGE) {
@@ -344,14 +337,14 @@ export default class Snapshot implements Snapshot {
344
337
  let value = relationship.getData();
345
338
  let data = value && value.data;
346
339
 
347
- inverseInternalModel = data ? store._instanceCache._internalModelForResource(data) : null;
340
+ let inverseIdentifier = data ? store.identifierCache.getOrCreateRecordIdentifier(data) : null;
348
341
 
349
342
  if (value && value.data !== undefined) {
350
- if (inverseInternalModel && !inverseInternalModel.isDeleted()) {
343
+ if (inverseIdentifier && !store._instanceCache.getRecordData(inverseIdentifier).isDeleted(inverseIdentifier)) {
351
344
  if (returnModeIsId) {
352
- result = inverseInternalModel.id;
345
+ result = inverseIdentifier.id;
353
346
  } else {
354
- result = store._instanceCache.createSnapshot(inverseInternalModel.identifier);
347
+ result = store._instanceCache.createSnapshot(inverseIdentifier);
355
348
  }
356
349
  } else {
357
350
  result = null;
@@ -411,7 +404,7 @@ export default class Snapshot implements Snapshot {
411
404
  return cachedSnapshots;
412
405
  }
413
406
 
414
- let store = this._internalModel.store;
407
+ let store = this._store;
415
408
  let relationshipMeta = store.getSchemaDefinitionService().relationshipsDefinitionFor({ type: this.modelName })[
416
409
  keyName
417
410
  ];
@@ -422,7 +415,7 @@ export default class Snapshot implements Snapshot {
422
415
 
423
416
  // TODO @runspired it seems this code branch would not work with CUSTOM_MODEL_CLASSes
424
417
  // this check is not a regression in behavior because relationships don't currently
425
- // function without access to intimate API contracts between RecordData and InternalModel.
418
+ // function without access to intimate API contracts between RecordData and Model.
426
419
  // This is a requirement we should fix as soon as the relationship layer does not require
427
420
  // this intimate API usage.
428
421
  if (!HAS_RECORD_DATA_PACKAGE) {
@@ -448,14 +441,12 @@ export default class Snapshot implements Snapshot {
448
441
  if (value.data) {
449
442
  results = [];
450
443
  value.data.forEach((member) => {
451
- let internalModel = store._instanceCache._internalModelForResource(member);
452
- if (!internalModel.isDeleted()) {
444
+ let inverseIdentifier = store.identifierCache.getOrCreateRecordIdentifier(member);
445
+ if (!store._instanceCache.getRecordData(inverseIdentifier).isDeleted(inverseIdentifier)) {
453
446
  if (returnModeIsIds) {
454
- (results as RecordId[]).push(
455
- (member as ExistingResourceIdentifierObject | NewResourceIdentifierObject).id || null
456
- );
447
+ (results as RecordId[]).push(inverseIdentifier.id);
457
448
  } else {
458
- (results as Snapshot[]).push(store._instanceCache.createSnapshot(internalModel.identifier));
449
+ (results as Snapshot[]).push(store._instanceCache.createSnapshot(inverseIdentifier));
459
450
  }
460
451
  }
461
452
  });
@@ -566,7 +557,7 @@ if (DEPRECATE_SNAPSHOT_MODEL_CLASS_ACCESS) {
566
557
  since: { available: '4.5.0', enabled: '4.5.0' },
567
558
  }
568
559
  );
569
- return this._internalModel.modelClass;
560
+ return this._store.modelFor(this.identifier.type);
570
561
  },
571
562
  });
572
563
  }
@@ -31,10 +31,10 @@ import { PromiseArrayProxy, PromiseObjectProxy } from './promise-proxy-base';
31
31
  promise: $.getJSON('/some/remote/data.json')
32
32
  });
33
33
 
34
- promiseArray.get('length'); // 0
34
+ promiseArray.length; // 0
35
35
 
36
36
  promiseArray.then(function() {
37
- promiseArray.get('length'); // 100
37
+ promiseArray.length; // 100
38
38
  });
39
39
  ```
40
40
 
@@ -77,10 +77,10 @@ export class PromiseArray<I, T extends EmberArrayLike<I>> extends PromiseArrayPr
77
77
  promise: $.getJSON('/some/remote/data.json')
78
78
  });
79
79
 
80
- promiseObject.get('name'); // null
80
+ promiseObject.name; // null
81
81
 
82
82
  promiseObject.then(function() {
83
- promiseObject.get('name'); // 'Tomster'
83
+ promiseObject.name; // 'Tomster'
84
84
  });
85
85
  ```
86
86
 
@@ -91,13 +91,13 @@ export class PromiseArray<I, T extends EmberArrayLike<I>> extends PromiseArrayPr
91
91
  */
92
92
  export { PromiseObjectProxy as PromiseObject };
93
93
 
94
- export function promiseObject<T>(promise: Promise<T>, label?: string): PromiseObjectProxy<T> {
94
+ function _promiseObject<T>(promise: Promise<T>, label?: string): PromiseObjectProxy<T> {
95
95
  return PromiseObjectProxy.create({
96
96
  promise: resolve(promise, label),
97
97
  }) as PromiseObjectProxy<T>;
98
98
  }
99
99
 
100
- export function promiseArray<I, T extends EmberArrayLike<I>>(promise: Promise<T>, label?: string): PromiseArray<I, T> {
100
+ function _promiseArray<I, T extends EmberArrayLike<I>>(promise: Promise<T>, label?: string): PromiseArray<I, T> {
101
101
  return PromiseArray.create({
102
102
  promise: resolve(promise, label),
103
103
  }) as unknown as PromiseArray<I, T>;
@@ -105,35 +105,96 @@ export function promiseArray<I, T extends EmberArrayLike<I>>(promise: Promise<T>
105
105
 
106
106
  // constructor is accessed in some internals but not including it in the copyright for the deprecation
107
107
  const ALLOWABLE_METHODS = ['constructor', 'then', 'catch', 'finally'];
108
+ const PROXIED_ARRAY_PROPS = [
109
+ 'length',
110
+ '[]',
111
+ 'firstObject',
112
+ 'lastObject',
113
+ 'meta',
114
+ 'content',
115
+ 'isPending',
116
+ 'isSettled',
117
+ 'isRejected',
118
+ 'isFulfilled',
119
+ 'promise',
120
+ 'reason',
121
+ ];
122
+ const PROXIED_OBJECT_PROPS = ['content', 'isPending', 'isSettled', 'isRejected', 'isFulfilled', 'promise', 'reason'];
123
+
124
+ export function promiseArray<I, T extends EmberArrayLike<I>>(promise: Promise<T>): PromiseArray<I, T> {
125
+ const promiseObjectProxy: PromiseArray<I, T> = _promiseArray(promise);
126
+ const handler = {
127
+ get(target: object, prop: string, receiver?: object): unknown {
128
+ if (typeof prop === 'symbol') {
129
+ return Reflect.get(target, prop, receiver);
130
+ }
131
+ if (!ALLOWABLE_METHODS.includes(prop)) {
132
+ deprecate(
133
+ `Accessing ${prop} on this PromiseArray is deprecated. The return type is being changed from PromiseArray to a Promise. The only available methods to access on this promise are .then, .catch and .finally`,
134
+ false,
135
+ {
136
+ id: 'ember-data:deprecate-promise-proxies',
137
+ until: '5.0',
138
+ for: '@ember-data/store',
139
+ since: {
140
+ available: '4.8',
141
+ enabled: '4.8',
142
+ },
143
+ }
144
+ );
145
+ }
108
146
 
109
- export function deprecatedPromiseObject<T>(promise: Promise<T>): PromiseObjectProxy<T> {
110
- const promiseObjectProxy: PromiseObjectProxy<T> = promiseObject(promise);
147
+ const value: unknown = target[prop];
148
+ if (value && typeof value === 'function' && typeof value.bind === 'function') {
149
+ return value.bind(target);
150
+ }
151
+
152
+ if (PROXIED_ARRAY_PROPS.includes(prop)) {
153
+ return value;
154
+ }
155
+
156
+ return undefined;
157
+ },
158
+ };
159
+
160
+ return new Proxy(promiseObjectProxy, handler);
161
+ }
162
+
163
+ export function promiseObject<T>(promise: Promise<T>): PromiseObjectProxy<T> {
164
+ const promiseObjectProxy: PromiseObjectProxy<T> = _promiseObject(promise);
111
165
  const handler = {
112
166
  get(target: object, prop: string, receiver?: object): unknown {
167
+ if (typeof prop === 'symbol') {
168
+ return Reflect.get(target, prop, receiver);
169
+ }
113
170
  if (!ALLOWABLE_METHODS.includes(prop)) {
114
171
  deprecate(
115
- `Accessing ${prop} is deprecated. The return type is being changed fomr PromiseObjectProxy to a Promise. The only available methods to access on this promise are .then, .catch and .finally`,
172
+ `Accessing ${prop} on this PromiseObject is deprecated. The return type is being changed from PromiseObject to a Promise. The only available methods to access on this promise are .then, .catch and .finally`,
116
173
  false,
117
174
  {
118
- id: 'ember-data:model-save-promise',
175
+ id: 'ember-data:deprecate-promise-proxies',
119
176
  until: '5.0',
120
177
  for: '@ember-data/store',
121
178
  since: {
122
- available: '4.4',
123
- enabled: '4.4',
179
+ available: '4.8',
180
+ enabled: '4.8',
124
181
  },
125
182
  }
126
183
  );
127
184
  }
128
185
 
129
- const value: unknown = Reflect.get(target, prop, receiver);
186
+ const value: unknown = target[prop];
130
187
  if (value && typeof value === 'function' && typeof value.bind === 'function') {
131
188
  return value.bind(target);
132
189
  }
133
190
 
134
- return value;
191
+ if (PROXIED_OBJECT_PROPS.includes(prop)) {
192
+ return value;
193
+ }
194
+
195
+ return undefined;
135
196
  },
136
197
  };
137
198
 
138
- return new Proxy(promiseObjectProxy, handler) as PromiseObjectProxy<T>;
199
+ return new Proxy(promiseObjectProxy, handler);
139
200
  }