@ember-data/store 4.8.0-alpha.5 → 4.8.0-alpha.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.
- package/addon/-private/caches/instance-cache.ts +8 -9
- package/addon/-private/index.ts +10 -6
- package/addon/-private/legacy-model-support/shim-model-class.ts +1 -0
- package/addon/-private/managers/record-array-manager.ts +138 -59
- package/addon/-private/managers/record-data-manager.ts +120 -128
- package/addon/-private/managers/record-data-store-wrapper.ts +7 -1
- package/addon/-private/managers/record-notification-manager.ts +1 -0
- package/addon/-private/network/fetch-manager.ts +16 -1
- package/addon/-private/network/snapshot-record-array.ts +6 -6
- package/addon/-private/proxies/promise-proxies.ts +72 -11
- package/addon/-private/record-arrays/identifier-array.ts +924 -0
- package/addon/-private/store-service.ts +76 -47
- package/addon/-private/utils/promise-record.ts +2 -3
- package/package.json +4 -4
- package/addon/-private/record-arrays/adapter-populated-record-array.ts +0 -99
- package/addon/-private/record-arrays/record-array.ts +0 -289
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import { assert } from '@ember/debug';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { assert, deprecate } from '@ember/debug';
|
|
2
|
+
|
|
3
|
+
import type { LocalRelationshipOperation } from '@ember-data/record-data/-private/graph/-operations';
|
|
4
|
+
import type {
|
|
5
|
+
CollectionResourceRelationship,
|
|
6
|
+
SingleResourceRelationship,
|
|
7
|
+
} from '@ember-data/types/q/ember-data-json-api';
|
|
8
|
+
import type { StableRecordIdentifier } from '@ember-data/types/q/identifier';
|
|
9
|
+
import type { ChangedAttributesHash, RecordData, RecordDataV1 } from '@ember-data/types/q/record-data';
|
|
10
|
+
import type { JsonApiResource, JsonApiValidationError } from '@ember-data/types/q/record-data-json-api';
|
|
11
|
+
import type { Dict } from '@ember-data/types/q/utils';
|
|
8
12
|
|
|
9
13
|
import { isStableIdentifier } from '../caches/identifier-cache';
|
|
10
|
-
import Store from '../store-service';
|
|
14
|
+
import type Store from '../store-service';
|
|
11
15
|
|
|
12
16
|
/**
|
|
13
17
|
* The RecordDataManager wraps a RecordData cache
|
|
@@ -64,6 +68,19 @@ export class NonSingletonRecordDataManager implements RecordData {
|
|
|
64
68
|
this.#store = store;
|
|
65
69
|
this.#recordData = recordData;
|
|
66
70
|
this.#identifier = identifier;
|
|
71
|
+
|
|
72
|
+
if (this.#isDeprecated(recordData)) {
|
|
73
|
+
deprecate(
|
|
74
|
+
`This RecordData uses the deprecated V1 RecordData Spec. Upgrade to V2 to maintain compatibility.`,
|
|
75
|
+
false,
|
|
76
|
+
{
|
|
77
|
+
id: 'ember-data:deprecate-v1-cache',
|
|
78
|
+
until: '5.0',
|
|
79
|
+
since: { available: '4.8', enabled: '4.8' },
|
|
80
|
+
for: 'ember-data',
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
}
|
|
67
84
|
}
|
|
68
85
|
|
|
69
86
|
#isDeprecated(recordData: RecordData | RecordDataV1): recordData is RecordDataV1 {
|
|
@@ -111,6 +128,59 @@ export class NonSingletonRecordDataManager implements RecordData {
|
|
|
111
128
|
return recordData.pushData(identifier, data, hasRecord);
|
|
112
129
|
}
|
|
113
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Update resource data with a local mutation. Currently supports operations
|
|
133
|
+
* on relationships only.
|
|
134
|
+
*
|
|
135
|
+
* @method update
|
|
136
|
+
* @public
|
|
137
|
+
* @param operation
|
|
138
|
+
*/
|
|
139
|
+
// isCollection is only needed for interop with v1 cache
|
|
140
|
+
update(operation: LocalRelationshipOperation, isResource?: boolean): void {
|
|
141
|
+
if (this.#isDeprecated(this.#recordData)) {
|
|
142
|
+
const cache = this.#store._instanceCache;
|
|
143
|
+
switch (operation.op) {
|
|
144
|
+
case 'addToRelatedRecords':
|
|
145
|
+
this.#recordData.addToHasMany(
|
|
146
|
+
operation.field,
|
|
147
|
+
(operation.value as StableRecordIdentifier[]).map((i) => cache.getRecordData(i)),
|
|
148
|
+
operation.index
|
|
149
|
+
);
|
|
150
|
+
return;
|
|
151
|
+
case 'removeFromRelatedRecords':
|
|
152
|
+
this.#recordData.removeFromHasMany(
|
|
153
|
+
operation.field,
|
|
154
|
+
(operation.value as StableRecordIdentifier[]).map((i) => cache.getRecordData(i))
|
|
155
|
+
);
|
|
156
|
+
return;
|
|
157
|
+
case 'replaceRelatedRecords':
|
|
158
|
+
this.#recordData.setDirtyHasMany(
|
|
159
|
+
operation.field,
|
|
160
|
+
operation.value.map((i) => cache.getRecordData(i))
|
|
161
|
+
);
|
|
162
|
+
return;
|
|
163
|
+
case 'replaceRelatedRecord':
|
|
164
|
+
if (isResource) {
|
|
165
|
+
this.#recordData.setDirtyBelongsTo(
|
|
166
|
+
operation.field,
|
|
167
|
+
operation.value ? cache.getRecordData(operation.value) : null
|
|
168
|
+
);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
this.#recordData.removeFromHasMany(operation.field, [cache.getRecordData(operation.prior!)]);
|
|
172
|
+
this.#recordData.addToHasMany(operation.field, [cache.getRecordData(operation.value!)], operation.index);
|
|
173
|
+
return;
|
|
174
|
+
case 'sortRelatedRecords':
|
|
175
|
+
return;
|
|
176
|
+
default:
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
this.#recordData.update(operation);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
114
184
|
/**
|
|
115
185
|
* [LIFECYLCE] Signal to the cache that a new record has been instantiated on the client
|
|
116
186
|
*
|
|
@@ -457,25 +527,7 @@ export class NonSingletonRecordDataManager implements RecordData {
|
|
|
457
527
|
/**
|
|
458
528
|
* Mutate the current state of a belongsTo relationship
|
|
459
529
|
*
|
|
460
|
-
*
|
|
461
|
-
* @public
|
|
462
|
-
* @param identifier
|
|
463
|
-
* @param propertyName
|
|
464
|
-
* @param value
|
|
465
|
-
*/
|
|
466
|
-
setBelongsTo(identifier: StableRecordIdentifier, propertyName: string, value: StableRecordIdentifier | null) {
|
|
467
|
-
const store = this.#store;
|
|
468
|
-
const recordData = this.#recordData;
|
|
469
|
-
|
|
470
|
-
this.#isDeprecated(recordData)
|
|
471
|
-
? recordData.setDirtyBelongsTo(propertyName, value ? store._instanceCache.getRecordData(value) : null)
|
|
472
|
-
: recordData.setBelongsTo(identifier, propertyName, value);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
/**
|
|
476
|
-
* Mutate the current state of a belongsTo relationship
|
|
477
|
-
*
|
|
478
|
-
* DEPRECATED use setBelongsTo
|
|
530
|
+
* DEPRECATED use update
|
|
479
531
|
*
|
|
480
532
|
* @method setDirtyBelongsTo
|
|
481
533
|
* @public
|
|
@@ -487,8 +539,13 @@ export class NonSingletonRecordDataManager implements RecordData {
|
|
|
487
539
|
const recordData = this.#recordData;
|
|
488
540
|
|
|
489
541
|
this.#isDeprecated(recordData)
|
|
490
|
-
? recordData.setDirtyBelongsTo(propertyName, value
|
|
491
|
-
: recordData.
|
|
542
|
+
? recordData.setDirtyBelongsTo(propertyName, value)
|
|
543
|
+
: recordData.update({
|
|
544
|
+
op: 'replaceRelatedRecord',
|
|
545
|
+
record: this.#identifier,
|
|
546
|
+
field: propertyName,
|
|
547
|
+
value: value ? value.getResourceIdentifier() : null,
|
|
548
|
+
});
|
|
492
549
|
}
|
|
493
550
|
|
|
494
551
|
/**
|
|
@@ -496,98 +553,52 @@ export class NonSingletonRecordDataManager implements RecordData {
|
|
|
496
553
|
* An index may optionally be specified which the cache should use for
|
|
497
554
|
* where in the list to insert the records
|
|
498
555
|
*
|
|
556
|
+
* DEPRECATED use update
|
|
557
|
+
*
|
|
499
558
|
* @method addToHasMany
|
|
559
|
+
* @deprecated
|
|
500
560
|
* @public
|
|
501
|
-
* @param identifier
|
|
502
561
|
* @param propertyName
|
|
503
562
|
* @param value
|
|
504
563
|
* @param idx
|
|
505
564
|
*/
|
|
506
|
-
addToHasMany(
|
|
507
|
-
identifier
|
|
508
|
-
propertyName: string,
|
|
509
|
-
value: StableRecordIdentifier[],
|
|
510
|
-
idx?: number
|
|
511
|
-
): void {
|
|
512
|
-
// called by something V1
|
|
513
|
-
let isFromV1 = false;
|
|
514
|
-
if (!isStableIdentifier(identifier)) {
|
|
515
|
-
isFromV1 = true;
|
|
516
|
-
idx = value as unknown as number;
|
|
517
|
-
value = propertyName as unknown as StableRecordIdentifier[];
|
|
518
|
-
propertyName = identifier as unknown as string;
|
|
519
|
-
identifier = this.#identifier;
|
|
520
|
-
}
|
|
521
|
-
const cache = this.#store._instanceCache;
|
|
565
|
+
addToHasMany(propertyName: string, value: NonSingletonRecordDataManager[], idx?: number): void {
|
|
566
|
+
const identifier = this.#identifier;
|
|
522
567
|
const recordData = this.#recordData;
|
|
523
568
|
|
|
524
569
|
this.#isDeprecated(recordData)
|
|
525
|
-
? recordData.addToHasMany(
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
propertyName,
|
|
533
|
-
isFromV1
|
|
534
|
-
? (value as unknown as NonSingletonRecordDataManager[]).map((v) => v.getResourceIdentifier())
|
|
535
|
-
: value,
|
|
536
|
-
idx
|
|
537
|
-
);
|
|
570
|
+
? recordData.addToHasMany(propertyName, value, idx)
|
|
571
|
+
: recordData.update({
|
|
572
|
+
op: 'addToRelatedRecords',
|
|
573
|
+
field: propertyName,
|
|
574
|
+
record: identifier,
|
|
575
|
+
value: value.map((v) => v.getResourceIdentifier()),
|
|
576
|
+
});
|
|
538
577
|
}
|
|
539
578
|
|
|
540
579
|
/**
|
|
541
580
|
* Mutate the current state of a hasMany relationship by removing values.
|
|
542
581
|
*
|
|
543
|
-
*
|
|
544
|
-
* @public
|
|
545
|
-
* @param identifier
|
|
546
|
-
* @param propertyName
|
|
547
|
-
* @param value
|
|
548
|
-
*/
|
|
549
|
-
removeFromHasMany(identifier: StableRecordIdentifier, propertyName: string, value: StableRecordIdentifier[]): void {
|
|
550
|
-
let isFromV1 = false;
|
|
551
|
-
if (!isStableIdentifier(identifier)) {
|
|
552
|
-
isFromV1 = true;
|
|
553
|
-
value = propertyName as unknown as StableRecordIdentifier[];
|
|
554
|
-
propertyName = identifier as unknown as string;
|
|
555
|
-
identifier = this.#identifier;
|
|
556
|
-
}
|
|
557
|
-
const cache = this.#store._instanceCache;
|
|
558
|
-
const recordData = this.#recordData;
|
|
559
|
-
|
|
560
|
-
this.#isDeprecated(recordData)
|
|
561
|
-
? recordData.removeFromHasMany(
|
|
562
|
-
propertyName,
|
|
563
|
-
isFromV1 ? (value as unknown as RecordData[]) : value.map((v) => cache.getRecordData(v))
|
|
564
|
-
)
|
|
565
|
-
: recordData.removeFromHasMany(
|
|
566
|
-
identifier,
|
|
567
|
-
propertyName,
|
|
568
|
-
isFromV1 ? (value as unknown as NonSingletonRecordDataManager[]).map((v) => v.getResourceIdentifier()) : value
|
|
569
|
-
);
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
/**
|
|
573
|
-
* Mutate the current state of a hasMany relationship by replacing it entirely
|
|
582
|
+
* DEPRECATED use update
|
|
574
583
|
*
|
|
575
|
-
* @method
|
|
584
|
+
* @method removeFromHasMany
|
|
585
|
+
* @deprecated
|
|
576
586
|
* @public
|
|
577
|
-
* @param identifier
|
|
578
587
|
* @param propertyName
|
|
579
588
|
* @param value
|
|
580
589
|
*/
|
|
581
|
-
|
|
582
|
-
const
|
|
590
|
+
removeFromHasMany(propertyName: string, value: RecordData[]): void {
|
|
591
|
+
const identifier = this.#identifier;
|
|
583
592
|
const recordData = this.#recordData;
|
|
584
593
|
|
|
585
594
|
this.#isDeprecated(recordData)
|
|
586
|
-
? recordData.
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
595
|
+
? recordData.removeFromHasMany(propertyName, value)
|
|
596
|
+
: recordData.update({
|
|
597
|
+
op: 'removeFromRelatedRecords',
|
|
598
|
+
record: identifier,
|
|
599
|
+
field: propertyName,
|
|
600
|
+
value: (value as unknown as NonSingletonRecordDataManager[]).map((v) => v.getResourceIdentifier()),
|
|
601
|
+
});
|
|
591
602
|
}
|
|
592
603
|
|
|
593
604
|
/**
|
|
@@ -601,16 +612,17 @@ export class NonSingletonRecordDataManager implements RecordData {
|
|
|
601
612
|
* @param propertyName
|
|
602
613
|
* @param value
|
|
603
614
|
*/
|
|
604
|
-
setDirtyHasMany(propertyName: string, value:
|
|
615
|
+
setDirtyHasMany(propertyName: string, value: NonSingletonRecordDataManager[]) {
|
|
605
616
|
let recordData = this.#recordData;
|
|
606
617
|
|
|
607
618
|
this.#isDeprecated(recordData)
|
|
608
619
|
? recordData.setDirtyHasMany(propertyName, value)
|
|
609
|
-
: recordData.
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
620
|
+
: recordData.update({
|
|
621
|
+
op: 'replaceRelatedRecords',
|
|
622
|
+
record: this.#identifier,
|
|
623
|
+
field: propertyName,
|
|
624
|
+
value: value.map((rd) => rd.getResourceIdentifier()),
|
|
625
|
+
});
|
|
614
626
|
}
|
|
615
627
|
|
|
616
628
|
// State
|
|
@@ -706,11 +718,9 @@ export class NonSingletonRecordDataManager implements RecordData {
|
|
|
706
718
|
export class SingletonRecordDataManager implements RecordData {
|
|
707
719
|
version: '2' = '2';
|
|
708
720
|
|
|
709
|
-
#store: Store;
|
|
710
721
|
#recordDatas: Map<StableRecordIdentifier, RecordData>;
|
|
711
722
|
|
|
712
|
-
constructor(
|
|
713
|
-
this.#store = store;
|
|
723
|
+
constructor() {
|
|
714
724
|
this.#recordDatas = new Map();
|
|
715
725
|
}
|
|
716
726
|
|
|
@@ -779,26 +789,8 @@ export class SingletonRecordDataManager implements RecordData {
|
|
|
779
789
|
): SingleResourceRelationship | CollectionResourceRelationship {
|
|
780
790
|
return this.#recordData(identifier).getRelationship(identifier, propertyName);
|
|
781
791
|
}
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
this.#recordData(identifier).setBelongsTo(identifier, propertyName, value);
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
addToHasMany(
|
|
788
|
-
identifier: StableRecordIdentifier,
|
|
789
|
-
propertyName: string,
|
|
790
|
-
value: StableRecordIdentifier[],
|
|
791
|
-
idx?: number
|
|
792
|
-
): void {
|
|
793
|
-
this.#recordData(identifier).addToHasMany(identifier, propertyName, value, idx);
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
removeFromHasMany(identifier: StableRecordIdentifier, propertyName: string, value: StableRecordIdentifier[]): void {
|
|
797
|
-
this.#recordData(identifier).removeFromHasMany(identifier, propertyName, value);
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
setHasMany(identifier: StableRecordIdentifier, propertyName: string, value: StableRecordIdentifier[]): void {
|
|
801
|
-
this.#recordData(identifier).setHasMany(identifier, propertyName, value);
|
|
792
|
+
update(operation: LocalRelationshipOperation): void {
|
|
793
|
+
this.#recordData(operation.record).update(operation);
|
|
802
794
|
}
|
|
803
795
|
|
|
804
796
|
// State
|
|
@@ -350,7 +350,13 @@ class V2RecordDataStoreWrapper implements StoreWrapper {
|
|
|
350
350
|
}
|
|
351
351
|
|
|
352
352
|
this._willNotify = true;
|
|
353
|
-
|
|
353
|
+
// it's possible a RecordData adhoc notifies us,
|
|
354
|
+
// in which case we sync flush
|
|
355
|
+
if (this._store._cbs) {
|
|
356
|
+
this._store._schedule('notify', () => this._flushNotifications());
|
|
357
|
+
} else {
|
|
358
|
+
this._flushNotifications();
|
|
359
|
+
}
|
|
354
360
|
}
|
|
355
361
|
|
|
356
362
|
_flushNotifications(): void {
|
|
@@ -5,8 +5,10 @@ import { assert, deprecate, warn } from '@ember/debug';
|
|
|
5
5
|
import { _backburner as emberBackburner } from '@ember/runloop';
|
|
6
6
|
import { DEBUG } from '@glimmer/env';
|
|
7
7
|
|
|
8
|
+
import { importSync } from '@embroider/macros';
|
|
8
9
|
import { default as RSVP, resolve } from 'rsvp';
|
|
9
10
|
|
|
11
|
+
import { HAS_RECORD_DATA_PACKAGE } from '@ember-data/private-build-infra';
|
|
10
12
|
import { DEPRECATE_RSVP_PROMISE } from '@ember-data/private-build-infra/deprecations';
|
|
11
13
|
import type { CollectionResourceDocument, SingleResourceDocument } from '@ember-data/types/q/ember-data-json-api';
|
|
12
14
|
import type { FindRecordQuery, Request, SaveRecordMutation } from '@ember-data/types/q/fetch-manager';
|
|
@@ -214,7 +216,20 @@ export default class FetchManager {
|
|
|
214
216
|
(error) => {
|
|
215
217
|
const recordData = store._instanceCache.peek({ identifier, bucket: 'recordData' });
|
|
216
218
|
if (!recordData || recordData.isEmpty(identifier) || isLoading) {
|
|
217
|
-
|
|
219
|
+
let isReleasable = true;
|
|
220
|
+
if (!recordData && HAS_RECORD_DATA_PACKAGE) {
|
|
221
|
+
const graphFor = (
|
|
222
|
+
importSync('@ember-data/record-data/-private') as typeof import('@ember-data/record-data/-private')
|
|
223
|
+
).graphFor;
|
|
224
|
+
const graph = graphFor(store);
|
|
225
|
+
isReleasable = graph.isReleasable(identifier);
|
|
226
|
+
if (!isReleasable) {
|
|
227
|
+
graph.unload(identifier, true);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (recordData || isReleasable) {
|
|
231
|
+
store._instanceCache.unloadRecord(identifier);
|
|
232
|
+
}
|
|
218
233
|
}
|
|
219
234
|
throw error;
|
|
220
235
|
}
|
|
@@ -10,7 +10,8 @@ import { StableRecordIdentifier } from '@ember-data/types/q/identifier';
|
|
|
10
10
|
import type { FindOptions } from '@ember-data/types/q/store';
|
|
11
11
|
import type { Dict } from '@ember-data/types/q/utils';
|
|
12
12
|
|
|
13
|
-
import type
|
|
13
|
+
import type IdentifierArray from '../record-arrays/identifier-array';
|
|
14
|
+
import { SOURCE } from '../record-arrays/identifier-array';
|
|
14
15
|
import Store from '../store-service';
|
|
15
16
|
import type Snapshot from './snapshot';
|
|
16
17
|
/**
|
|
@@ -23,12 +24,11 @@ import type Snapshot from './snapshot';
|
|
|
23
24
|
*/
|
|
24
25
|
export default class SnapshotRecordArray {
|
|
25
26
|
declare _snapshots: Snapshot[] | null;
|
|
26
|
-
declare _recordArray:
|
|
27
|
+
declare _recordArray: IdentifierArray;
|
|
27
28
|
declare _type: ModelSchema | null;
|
|
28
29
|
declare __store: Store;
|
|
29
30
|
|
|
30
31
|
declare length: number;
|
|
31
|
-
declare meta: Dict<unknown> | null;
|
|
32
32
|
declare adapterOptions?: Dict<unknown>;
|
|
33
33
|
declare include?: string;
|
|
34
34
|
|
|
@@ -41,10 +41,9 @@ export default class SnapshotRecordArray {
|
|
|
41
41
|
@private
|
|
42
42
|
@constructor
|
|
43
43
|
@param {RecordArray} recordArray
|
|
44
|
-
@param {Object} meta
|
|
45
44
|
@param options
|
|
46
45
|
*/
|
|
47
|
-
constructor(store: Store, recordArray:
|
|
46
|
+
constructor(store: Store, recordArray: IdentifierArray, options: FindOptions = {}) {
|
|
48
47
|
this.__store = store;
|
|
49
48
|
/**
|
|
50
49
|
An array of snapshots
|
|
@@ -181,8 +180,9 @@ export default class SnapshotRecordArray {
|
|
|
181
180
|
if (this._snapshots !== null) {
|
|
182
181
|
return this._snapshots;
|
|
183
182
|
}
|
|
183
|
+
|
|
184
184
|
const { _instanceCache } = this.__store;
|
|
185
|
-
this._snapshots = this._recordArray.
|
|
185
|
+
this._snapshots = this._recordArray[SOURCE].map((identifier: StableRecordIdentifier) =>
|
|
186
186
|
_instanceCache.createSnapshot(identifier)
|
|
187
187
|
);
|
|
188
188
|
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
110
|
-
|
|
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
|
|
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:
|
|
175
|
+
id: 'ember-data:deprecate-promise-proxies',
|
|
119
176
|
until: '5.0',
|
|
120
177
|
for: '@ember-data/store',
|
|
121
178
|
since: {
|
|
122
|
-
available: '4.
|
|
123
|
-
enabled: '4.
|
|
179
|
+
available: '4.8',
|
|
180
|
+
enabled: '4.8',
|
|
124
181
|
},
|
|
125
182
|
}
|
|
126
183
|
);
|
|
127
184
|
}
|
|
128
185
|
|
|
129
|
-
const value: unknown =
|
|
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
|
-
|
|
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)
|
|
199
|
+
return new Proxy(promiseObjectProxy, handler);
|
|
139
200
|
}
|