@ember-data/store 4.4.0 → 4.5.0-alpha.2
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/system/core-store.ts +136 -147
- package/addon/-private/system/ds-model-store.ts +1 -10
- package/addon/-private/system/fetch-manager.ts +48 -21
- package/addon/-private/system/model/internal-model.ts +263 -192
- package/addon/-private/system/model/states.js +5 -41
- package/addon/-private/system/{promise-proxies.js → promise-proxies.ts} +31 -21
- package/addon/-private/system/promise-proxy-base.js +7 -0
- package/addon/-private/system/{record-array-manager.js → record-array-manager.ts} +87 -60
- package/addon/-private/system/record-arrays/adapter-populated-record-array.ts +129 -0
- package/addon/-private/system/record-arrays/{record-array.js → record-array.ts} +96 -75
- package/addon/-private/system/record-data-for.ts +2 -0
- package/addon/-private/system/references/belongs-to.ts +3 -2
- package/addon/-private/system/references/has-many.ts +4 -2
- package/addon/-private/system/schema-definition-service.ts +2 -2
- package/addon/-private/system/snapshot-record-array.ts +12 -11
- package/addon/-private/system/snapshot.ts +24 -7
- package/addon/-private/system/store/common.js +24 -1
- package/addon/-private/system/store/finders.js +53 -5
- package/addon/-private/system/store/internal-model-factory.ts +8 -7
- package/addon/-private/system/store/record-data-store-wrapper.ts +7 -2
- package/addon/-private/system/store/serializer-response.ts +85 -0
- package/addon/-private/ts-interfaces/ds-model.ts +15 -7
- package/addon/-private/ts-interfaces/ember-data-json-api.ts +3 -0
- package/addon/-private/ts-interfaces/minimum-adapter-interface.ts +19 -20
- package/addon/-private/ts-interfaces/minimum-serializer-interface.ts +27 -6
- package/addon/-private/ts-interfaces/record-data.ts +4 -1
- package/addon/-private/ts-interfaces/record-instance.ts +3 -1
- package/addon/-private/ts-interfaces/store.ts +1 -0
- package/addon/-private/utils/promise-record.ts +3 -3
- package/index.js +3 -0
- package/package.json +7 -6
- package/addon/-private/system/record-arrays/adapter-populated-record-array.js +0 -95
- package/addon/-private/system/store/serializer-response.js +0 -71
|
@@ -262,7 +262,6 @@ const DirtyState = {
|
|
|
262
262
|
|
|
263
263
|
rolledBack(internalModel) {
|
|
264
264
|
internalModel.transitionTo('loaded.saved');
|
|
265
|
-
internalModel.triggerLater('rolledBack');
|
|
266
265
|
},
|
|
267
266
|
|
|
268
267
|
becameInvalid(internalModel) {
|
|
@@ -271,7 +270,6 @@ const DirtyState = {
|
|
|
271
270
|
|
|
272
271
|
rollback(internalModel) {
|
|
273
272
|
internalModel.rollbackAttributes();
|
|
274
|
-
internalModel.triggerLater('ready');
|
|
275
273
|
},
|
|
276
274
|
},
|
|
277
275
|
|
|
@@ -297,9 +295,7 @@ const DirtyState = {
|
|
|
297
295
|
internalModel.send('invokeLifecycleCallbacks', this.dirtyType);
|
|
298
296
|
},
|
|
299
297
|
|
|
300
|
-
rolledBack(
|
|
301
|
-
internalModel.triggerLater('rolledBack');
|
|
302
|
-
},
|
|
298
|
+
rolledBack() {},
|
|
303
299
|
|
|
304
300
|
becameInvalid(internalModel) {
|
|
305
301
|
internalModel.transitionTo('invalid');
|
|
@@ -308,7 +304,6 @@ const DirtyState = {
|
|
|
308
304
|
|
|
309
305
|
becameError(internalModel) {
|
|
310
306
|
internalModel.transitionTo('uncommitted');
|
|
311
|
-
internalModel.triggerLater('becameError', internalModel);
|
|
312
307
|
},
|
|
313
308
|
},
|
|
314
309
|
|
|
@@ -345,16 +340,13 @@ const DirtyState = {
|
|
|
345
340
|
rolledBack(internalModel) {
|
|
346
341
|
clearErrorMessages(internalModel);
|
|
347
342
|
internalModel.transitionTo('loaded.saved');
|
|
348
|
-
internalModel.triggerLater('ready');
|
|
349
343
|
},
|
|
350
344
|
|
|
351
345
|
becameValid(internalModel) {
|
|
352
346
|
internalModel.transitionTo('uncommitted');
|
|
353
347
|
},
|
|
354
348
|
|
|
355
|
-
invokeLifecycleCallbacks(
|
|
356
|
-
internalModel.triggerLater('becameInvalid', internalModel);
|
|
357
|
-
},
|
|
349
|
+
invokeLifecycleCallbacks() {},
|
|
358
350
|
},
|
|
359
351
|
};
|
|
360
352
|
|
|
@@ -403,12 +395,10 @@ const createdState = dirtyState({
|
|
|
403
395
|
|
|
404
396
|
createdState.invalid.rolledBack = function (internalModel) {
|
|
405
397
|
internalModel.transitionTo('deleted.saved');
|
|
406
|
-
internalModel.triggerLater('rolledBack');
|
|
407
398
|
};
|
|
408
399
|
|
|
409
400
|
createdState.uncommitted.rolledBack = function (internalModel) {
|
|
410
401
|
internalModel.transitionTo('deleted.saved');
|
|
411
|
-
internalModel.triggerLater('rolledBack');
|
|
412
402
|
};
|
|
413
403
|
|
|
414
404
|
const updatedState = dirtyState({
|
|
@@ -433,7 +423,6 @@ createdState.uncommitted.pushedData = function (internalModel) {
|
|
|
433
423
|
// TODO @runspired consider where to do this once we kill off state machine
|
|
434
424
|
internalModel.store._notificationManager.notify(internalModel.identifier, 'identity');
|
|
435
425
|
internalModel.transitionTo('loaded.updated.uncommitted');
|
|
436
|
-
internalModel.triggerLater('didLoad');
|
|
437
426
|
};
|
|
438
427
|
|
|
439
428
|
createdState.uncommitted.propertyWasReset = function () {};
|
|
@@ -458,7 +447,6 @@ updatedState.uncommitted.deleteRecord = function (internalModel) {
|
|
|
458
447
|
updatedState.invalid.rolledBack = function (internalModel) {
|
|
459
448
|
clearErrorMessages(internalModel);
|
|
460
449
|
internalModel.transitionTo('loaded.saved');
|
|
461
|
-
internalModel.triggerLater('rolledBack');
|
|
462
450
|
};
|
|
463
451
|
|
|
464
452
|
const RootState = {
|
|
@@ -500,13 +488,10 @@ const RootState = {
|
|
|
500
488
|
|
|
501
489
|
loadedData(internalModel) {
|
|
502
490
|
internalModel.transitionTo('loaded.created.uncommitted');
|
|
503
|
-
internalModel.triggerLater('ready');
|
|
504
491
|
},
|
|
505
492
|
|
|
506
493
|
pushedData(internalModel) {
|
|
507
494
|
internalModel.transitionTo('loaded.saved');
|
|
508
|
-
internalModel.triggerLater('didLoad');
|
|
509
|
-
internalModel.triggerLater('ready');
|
|
510
495
|
},
|
|
511
496
|
|
|
512
497
|
// Record is already in an empty state, triggering transition to empty here
|
|
@@ -533,15 +518,11 @@ const RootState = {
|
|
|
533
518
|
// EVENTS
|
|
534
519
|
pushedData(internalModel) {
|
|
535
520
|
internalModel.transitionTo('loaded.saved');
|
|
536
|
-
internalModel.triggerLater('didLoad');
|
|
537
|
-
internalModel.triggerLater('ready');
|
|
538
521
|
//TODO this seems out of place here
|
|
539
522
|
internalModel.didCleanError();
|
|
540
523
|
},
|
|
541
524
|
|
|
542
|
-
becameError(
|
|
543
|
-
internalModel.triggerLater('becameError', internalModel);
|
|
544
|
-
},
|
|
525
|
+
becameError() {},
|
|
545
526
|
|
|
546
527
|
notFound(internalModel) {
|
|
547
528
|
internalModel.transitionTo('empty');
|
|
@@ -640,7 +621,6 @@ const RootState = {
|
|
|
640
621
|
|
|
641
622
|
rollback(internalModel) {
|
|
642
623
|
internalModel.rollbackAttributes();
|
|
643
|
-
internalModel.triggerLater('ready');
|
|
644
624
|
},
|
|
645
625
|
|
|
646
626
|
pushedData() {},
|
|
@@ -649,8 +629,6 @@ const RootState = {
|
|
|
649
629
|
|
|
650
630
|
rolledBack(internalModel) {
|
|
651
631
|
internalModel.transitionTo('loaded.saved');
|
|
652
|
-
internalModel.triggerLater('ready');
|
|
653
|
-
internalModel.triggerLater('rolledBack');
|
|
654
632
|
},
|
|
655
633
|
},
|
|
656
634
|
|
|
@@ -676,12 +654,10 @@ const RootState = {
|
|
|
676
654
|
|
|
677
655
|
becameError(internalModel) {
|
|
678
656
|
internalModel.transitionTo('uncommitted');
|
|
679
|
-
internalModel.triggerLater('becameError', internalModel);
|
|
680
657
|
},
|
|
681
658
|
|
|
682
659
|
becameInvalid(internalModel) {
|
|
683
660
|
internalModel.transitionTo('invalid');
|
|
684
|
-
internalModel.triggerLater('becameInvalid', internalModel);
|
|
685
661
|
},
|
|
686
662
|
},
|
|
687
663
|
|
|
@@ -696,10 +672,7 @@ const RootState = {
|
|
|
696
672
|
internalModel.removeFromInverseRelationships();
|
|
697
673
|
},
|
|
698
674
|
|
|
699
|
-
invokeLifecycleCallbacks(
|
|
700
|
-
internalModel.triggerLater('didDelete', internalModel);
|
|
701
|
-
internalModel.triggerLater('didCommit', internalModel);
|
|
702
|
-
},
|
|
675
|
+
invokeLifecycleCallbacks() {},
|
|
703
676
|
|
|
704
677
|
willCommit() {},
|
|
705
678
|
didCommit() {},
|
|
@@ -727,7 +700,6 @@ const RootState = {
|
|
|
727
700
|
rolledBack(internalModel) {
|
|
728
701
|
clearErrorMessages(internalModel);
|
|
729
702
|
internalModel.transitionTo('loaded.saved');
|
|
730
|
-
internalModel.triggerLater('ready');
|
|
731
703
|
},
|
|
732
704
|
|
|
733
705
|
becameValid(internalModel) {
|
|
@@ -736,15 +708,7 @@ const RootState = {
|
|
|
736
708
|
},
|
|
737
709
|
},
|
|
738
710
|
|
|
739
|
-
invokeLifecycleCallbacks(
|
|
740
|
-
if (dirtyType === 'created') {
|
|
741
|
-
internalModel.triggerLater('didCreate', internalModel);
|
|
742
|
-
} else {
|
|
743
|
-
internalModel.triggerLater('didUpdate', internalModel);
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
internalModel.triggerLater('didCommit', internalModel);
|
|
747
|
-
},
|
|
711
|
+
invokeLifecycleCallbacks() {},
|
|
748
712
|
};
|
|
749
713
|
|
|
750
714
|
function wireState(object, parent, name) {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import ArrayProxy from '@ember/array/proxy';
|
|
2
1
|
import { deprecate } from '@ember/debug';
|
|
2
|
+
import type ComputedProperty from '@ember/object/computed';
|
|
3
3
|
import { reads } from '@ember/object/computed';
|
|
4
|
-
import PromiseProxyMixin from '@ember/object/promise-proxy-mixin';
|
|
5
|
-
import ObjectProxy from '@ember/object/proxy';
|
|
6
4
|
|
|
7
|
-
import {
|
|
5
|
+
import { resolve } from 'rsvp';
|
|
6
|
+
|
|
7
|
+
import type { Dict } from '../ts-interfaces/utils';
|
|
8
|
+
import { PromiseArrayProxy, PromiseObjectProxy } from './promise-proxy-base';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
@module @ember-data/store
|
|
@@ -41,9 +42,20 @@ import { Promise } from 'rsvp';
|
|
|
41
42
|
@extends Ember.ArrayProxy
|
|
42
43
|
@uses Ember.PromiseProxyMixin
|
|
43
44
|
*/
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
interface EmberNativeArrayLike<T> {
|
|
46
|
+
length: number | ComputedProperty<number>;
|
|
47
|
+
objectAt(idx: number): T | undefined;
|
|
48
|
+
}
|
|
49
|
+
interface EmberArrayProxyLike<T> {
|
|
50
|
+
length: number | ComputedProperty<number>;
|
|
51
|
+
objectAtContent(idx: number): T | undefined;
|
|
52
|
+
}
|
|
53
|
+
type EmberArrayLike<T> = EmberNativeArrayLike<T> | EmberArrayProxyLike<T>;
|
|
54
|
+
|
|
55
|
+
export class PromiseArray<I, T extends EmberArrayLike<I>> extends PromiseArrayProxy<I, T> {
|
|
56
|
+
@reads('content.meta')
|
|
57
|
+
declare meta?: Dict<unknown>;
|
|
58
|
+
}
|
|
47
59
|
|
|
48
60
|
/**
|
|
49
61
|
A `PromiseObject` is an object that acts like both an `EmberObject`
|
|
@@ -76,26 +88,26 @@ export const PromiseArray = ArrayProxy.extend(PromiseProxyMixin, {
|
|
|
76
88
|
@extends Ember.ObjectProxy
|
|
77
89
|
@uses Ember.PromiseProxyMixin
|
|
78
90
|
*/
|
|
79
|
-
export
|
|
91
|
+
export { PromiseObjectProxy as PromiseObject };
|
|
80
92
|
|
|
81
|
-
export function promiseObject(promise
|
|
82
|
-
return
|
|
83
|
-
promise:
|
|
84
|
-
})
|
|
93
|
+
export function promiseObject<T>(promise: Promise<T>, label?: string): PromiseObjectProxy<T> {
|
|
94
|
+
return PromiseObjectProxy.create({
|
|
95
|
+
promise: resolve(promise, label),
|
|
96
|
+
}) as PromiseObjectProxy<T>;
|
|
85
97
|
}
|
|
86
98
|
|
|
87
|
-
export function promiseArray(promise
|
|
99
|
+
export function promiseArray<I, T extends EmberArrayLike<I>>(promise: Promise<T>, label?: string): PromiseArray<I, T> {
|
|
88
100
|
return PromiseArray.create({
|
|
89
|
-
promise:
|
|
90
|
-
})
|
|
101
|
+
promise: resolve(promise, label),
|
|
102
|
+
}) as unknown as PromiseArray<I, T>;
|
|
91
103
|
}
|
|
92
104
|
|
|
93
105
|
// constructor is accessed in some internals but not including it in the copyright for the deprecation
|
|
94
106
|
const ALLOWABLE_METHODS = ['constructor', 'then', 'catch', 'finally'];
|
|
95
107
|
|
|
96
|
-
export function deprecatedPromiseObject(promise) {
|
|
108
|
+
export function deprecatedPromiseObject<T>(promise: PromiseObjectProxy<T>): PromiseObjectProxy<T> {
|
|
97
109
|
const handler = {
|
|
98
|
-
get(target, prop) {
|
|
110
|
+
get(target: object, prop: string, receiver?: object): unknown {
|
|
99
111
|
if (!ALLOWABLE_METHODS.includes(prop)) {
|
|
100
112
|
deprecate(
|
|
101
113
|
`Accessing ${prop} is deprecated. Only available methods to access on a promise returned from model.save() are .then, .catch and .finally`,
|
|
@@ -112,11 +124,9 @@ export function deprecatedPromiseObject(promise) {
|
|
|
112
124
|
);
|
|
113
125
|
}
|
|
114
126
|
|
|
115
|
-
|
|
116
|
-
return Reflect.get(...arguments).bind(target);
|
|
127
|
+
return (Reflect.get(target, prop, receiver) as Function).bind(target);
|
|
117
128
|
},
|
|
118
129
|
};
|
|
119
130
|
|
|
120
|
-
|
|
121
|
-
return new Proxy(promise, handler);
|
|
131
|
+
return new Proxy(promise, handler) as PromiseObjectProxy<T>;
|
|
122
132
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import ArrayProxy from '@ember/array/proxy';
|
|
2
|
+
import PromiseProxyMixin from '@ember/object/promise-proxy-mixin';
|
|
3
|
+
import ObjectProxy from '@ember/object/proxy';
|
|
4
|
+
|
|
5
|
+
export const PromiseArrayProxy = ArrayProxy.extend(PromiseProxyMixin);
|
|
6
|
+
|
|
7
|
+
export const PromiseObjectProxy = ObjectProxy.extend(PromiseProxyMixin);
|
|
@@ -4,37 +4,39 @@
|
|
|
4
4
|
|
|
5
5
|
import { A } from '@ember/array';
|
|
6
6
|
import { assert } from '@ember/debug';
|
|
7
|
-
import {
|
|
7
|
+
import { set } from '@ember/object';
|
|
8
8
|
import { _backburner as emberBackburner } from '@ember/runloop';
|
|
9
9
|
import { DEBUG } from '@glimmer/env';
|
|
10
10
|
|
|
11
|
-
import isStableIdentifier from '../identifiers/is-stable-identifier';
|
|
11
|
+
// import isStableIdentifier from '../identifiers/is-stable-identifier';
|
|
12
|
+
import type { CollectionResourceDocument, Meta } from '../ts-interfaces/ember-data-json-api';
|
|
13
|
+
import type { StableRecordIdentifier } from '../ts-interfaces/identifier';
|
|
14
|
+
import type { Dict } from '../ts-interfaces/utils';
|
|
15
|
+
import type CoreStore from './core-store';
|
|
12
16
|
import { AdapterPopulatedRecordArray, RecordArray } from './record-arrays';
|
|
13
17
|
import { internalModelFactoryFor } from './store/internal-model-factory';
|
|
14
18
|
import WeakCache from './weak-cache';
|
|
15
19
|
|
|
16
|
-
const RecordArraysCache = new WeakCache(DEBUG ? 'record-arrays' : '');
|
|
20
|
+
const RecordArraysCache = new WeakCache<StableRecordIdentifier, Set<RecordArray>>(DEBUG ? 'record-arrays' : '');
|
|
17
21
|
RecordArraysCache._generator = () => new Set();
|
|
18
|
-
export function recordArraysForIdentifier(
|
|
19
|
-
return RecordArraysCache.lookup(
|
|
22
|
+
export function recordArraysForIdentifier(identifier: StableRecordIdentifier): Set<RecordArray> {
|
|
23
|
+
return RecordArraysCache.lookup(identifier);
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
const pendingForIdentifier = new Set([]);
|
|
26
|
+
const pendingForIdentifier: Set<StableRecordIdentifier> = new Set([]);
|
|
23
27
|
|
|
24
|
-
function getIdentifier(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
i = identifierOrInternalModel.identifier || i;
|
|
32
|
-
}
|
|
28
|
+
function getIdentifier(identifier: StableRecordIdentifier): StableRecordIdentifier {
|
|
29
|
+
// during dematerialization we will get an identifier that
|
|
30
|
+
// has already been removed from the identifiers cache
|
|
31
|
+
// so it will not behave as if stable. This is a bug we should fix.
|
|
32
|
+
// if (!isStableIdentifier(identifierOrInternalModel)) {
|
|
33
|
+
// console.log({ unstable: i });
|
|
34
|
+
// }
|
|
33
35
|
|
|
34
|
-
return
|
|
36
|
+
return identifier;
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
function shouldIncludeInRecordArrays(store, identifier) {
|
|
39
|
+
function shouldIncludeInRecordArrays(store: CoreStore, identifier: StableRecordIdentifier): boolean {
|
|
38
40
|
const cache = internalModelFactoryFor(store);
|
|
39
41
|
const internalModel = cache.peek(identifier);
|
|
40
42
|
|
|
@@ -49,12 +51,19 @@ function shouldIncludeInRecordArrays(store, identifier) {
|
|
|
49
51
|
@internal
|
|
50
52
|
*/
|
|
51
53
|
class RecordArrayManager {
|
|
52
|
-
|
|
54
|
+
declare store: CoreStore;
|
|
55
|
+
declare isDestroying: boolean;
|
|
56
|
+
declare isDestroyed: boolean;
|
|
57
|
+
declare _liveRecordArrays: Dict<RecordArray>;
|
|
58
|
+
declare _pendingIdentifiers: Dict<StableRecordIdentifier[]>;
|
|
59
|
+
declare _adapterPopulatedRecordArrays: RecordArray[];
|
|
60
|
+
|
|
61
|
+
constructor(options: { store: CoreStore }) {
|
|
53
62
|
this.store = options.store;
|
|
54
63
|
this.isDestroying = false;
|
|
55
64
|
this.isDestroyed = false;
|
|
56
|
-
this._liveRecordArrays = Object.create(null)
|
|
57
|
-
this._pendingIdentifiers = Object.create(null)
|
|
65
|
+
this._liveRecordArrays = Object.create(null) as Dict<RecordArray>;
|
|
66
|
+
this._pendingIdentifiers = Object.create(null) as Dict<StableRecordIdentifier[]>;
|
|
58
67
|
this._adapterPopulatedRecordArrays = [];
|
|
59
68
|
}
|
|
60
69
|
|
|
@@ -64,15 +73,15 @@ class RecordArrayManager {
|
|
|
64
73
|
* @param {StableIdentifier} param
|
|
65
74
|
* @return {RecordArray} array
|
|
66
75
|
*/
|
|
67
|
-
getRecordArraysForIdentifier(identifier) {
|
|
76
|
+
getRecordArraysForIdentifier(identifier: StableRecordIdentifier): Set<RecordArray> {
|
|
68
77
|
return recordArraysForIdentifier(identifier);
|
|
69
78
|
}
|
|
70
79
|
|
|
71
|
-
_flushPendingIdentifiersForModelName(modelName, identifiers) {
|
|
80
|
+
_flushPendingIdentifiersForModelName(modelName: string, identifiers: StableRecordIdentifier[]): void {
|
|
72
81
|
if (this.isDestroying || this.isDestroyed) {
|
|
73
82
|
return;
|
|
74
83
|
}
|
|
75
|
-
let
|
|
84
|
+
let identifiersToRemove: StableRecordIdentifier[] = [];
|
|
76
85
|
|
|
77
86
|
for (let j = 0; j < identifiers.length; j++) {
|
|
78
87
|
let i = identifiers[j];
|
|
@@ -82,7 +91,7 @@ class RecordArrayManager {
|
|
|
82
91
|
// build up a set of models to ensure we have purged correctly;
|
|
83
92
|
let isIncluded = shouldIncludeInRecordArrays(this.store, i);
|
|
84
93
|
if (!isIncluded) {
|
|
85
|
-
|
|
94
|
+
identifiersToRemove.push(i);
|
|
86
95
|
}
|
|
87
96
|
}
|
|
88
97
|
|
|
@@ -94,30 +103,33 @@ class RecordArrayManager {
|
|
|
94
103
|
}
|
|
95
104
|
|
|
96
105
|
// process adapterPopulatedRecordArrays
|
|
97
|
-
if (
|
|
98
|
-
removeFromAdapterPopulatedRecordArrays(this.store,
|
|
106
|
+
if (identifiersToRemove.length > 0) {
|
|
107
|
+
removeFromAdapterPopulatedRecordArrays(this.store, identifiersToRemove);
|
|
99
108
|
}
|
|
100
109
|
}
|
|
101
110
|
|
|
102
111
|
_flush() {
|
|
103
112
|
let pending = this._pendingIdentifiers;
|
|
104
|
-
this._pendingIdentifiers = Object.create(null)
|
|
113
|
+
this._pendingIdentifiers = Object.create(null) as Dict<StableRecordIdentifier[]>;
|
|
105
114
|
|
|
106
115
|
for (let modelName in pending) {
|
|
107
|
-
this._flushPendingIdentifiersForModelName(modelName, pending[modelName]);
|
|
116
|
+
this._flushPendingIdentifiersForModelName(modelName, pending[modelName]!);
|
|
108
117
|
}
|
|
109
118
|
}
|
|
110
119
|
|
|
111
|
-
_syncLiveRecordArray(array, modelName) {
|
|
120
|
+
_syncLiveRecordArray(array: RecordArray, modelName: string) {
|
|
112
121
|
assert(
|
|
113
122
|
`recordArrayManger.syncLiveRecordArray expects modelName not modelClass as the second param`,
|
|
114
123
|
typeof modelName === 'string'
|
|
115
124
|
);
|
|
116
125
|
let pending = this._pendingIdentifiers[modelName];
|
|
117
|
-
|
|
118
|
-
|
|
126
|
+
|
|
127
|
+
if (!Array.isArray(pending)) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
let hasNoPotentialDeletions = pending.length === 0;
|
|
119
131
|
let map = internalModelFactoryFor(this.store).modelMapFor(modelName);
|
|
120
|
-
let hasNoInsertionsOrRemovals =
|
|
132
|
+
let hasNoInsertionsOrRemovals = map.length === array.length;
|
|
121
133
|
|
|
122
134
|
/*
|
|
123
135
|
Ideally the recordArrayManager has knowledge of the changes to be applied to
|
|
@@ -129,28 +141,26 @@ class RecordArrayManager {
|
|
|
129
141
|
return;
|
|
130
142
|
}
|
|
131
143
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
delete this._pendingIdentifiers[modelName];
|
|
135
|
-
}
|
|
144
|
+
this._flushPendingIdentifiersForModelName(modelName, pending);
|
|
145
|
+
delete this._pendingIdentifiers[modelName];
|
|
136
146
|
|
|
137
147
|
let identifiers = this._visibleIdentifiersByType(modelName);
|
|
138
|
-
let
|
|
148
|
+
let identifiersToAdd: StableRecordIdentifier[] = [];
|
|
139
149
|
for (let i = 0; i < identifiers.length; i++) {
|
|
140
150
|
let identifier = identifiers[i];
|
|
141
151
|
let recordArrays = recordArraysForIdentifier(identifier);
|
|
142
152
|
if (recordArrays.has(array) === false) {
|
|
143
153
|
recordArrays.add(array);
|
|
144
|
-
|
|
154
|
+
identifiersToAdd.push(identifier);
|
|
145
155
|
}
|
|
146
156
|
}
|
|
147
157
|
|
|
148
|
-
if (
|
|
149
|
-
array._pushIdentifiers(
|
|
158
|
+
if (identifiersToAdd.length) {
|
|
159
|
+
array._pushIdentifiers(identifiersToAdd);
|
|
150
160
|
}
|
|
151
161
|
}
|
|
152
162
|
|
|
153
|
-
_didUpdateAll(modelName) {
|
|
163
|
+
_didUpdateAll(modelName: string): void {
|
|
154
164
|
let recordArray = this._liveRecordArrays[modelName];
|
|
155
165
|
if (recordArray) {
|
|
156
166
|
set(recordArray, 'isUpdating', false);
|
|
@@ -166,7 +176,7 @@ class RecordArrayManager {
|
|
|
166
176
|
@param {String} modelName
|
|
167
177
|
@return {RecordArray}
|
|
168
178
|
*/
|
|
169
|
-
liveRecordArrayFor(modelName) {
|
|
179
|
+
liveRecordArrayFor(modelName: string): RecordArray {
|
|
170
180
|
assert(
|
|
171
181
|
`recordArrayManger.liveRecordArrayFor expects modelName not modelClass as the param`,
|
|
172
182
|
typeof modelName === 'string'
|
|
@@ -188,9 +198,9 @@ class RecordArrayManager {
|
|
|
188
198
|
return array;
|
|
189
199
|
}
|
|
190
200
|
|
|
191
|
-
_visibleIdentifiersByType(modelName) {
|
|
201
|
+
_visibleIdentifiersByType(modelName: string) {
|
|
192
202
|
let all = internalModelFactoryFor(this.store).modelMapFor(modelName).recordIdentifiers;
|
|
193
|
-
let visible = [];
|
|
203
|
+
let visible: StableRecordIdentifier[] = [];
|
|
194
204
|
for (let i = 0; i < all.length; i++) {
|
|
195
205
|
let identifier = all[i];
|
|
196
206
|
let shouldInclude = shouldIncludeInRecordArrays(this.store, identifier);
|
|
@@ -211,7 +221,7 @@ class RecordArrayManager {
|
|
|
211
221
|
@param {Array} [identifiers]
|
|
212
222
|
@return {RecordArray}
|
|
213
223
|
*/
|
|
214
|
-
createRecordArray(modelName, identifiers) {
|
|
224
|
+
createRecordArray(modelName: string, identifiers: StableRecordIdentifier[] = []): RecordArray {
|
|
215
225
|
assert(
|
|
216
226
|
`recordArrayManger.createRecordArray expects modelName not modelClass as the param`,
|
|
217
227
|
typeof modelName === 'string'
|
|
@@ -241,13 +251,18 @@ class RecordArrayManager {
|
|
|
241
251
|
@param {Object} query
|
|
242
252
|
@return {AdapterPopulatedRecordArray}
|
|
243
253
|
*/
|
|
244
|
-
createAdapterPopulatedRecordArray(
|
|
254
|
+
createAdapterPopulatedRecordArray(
|
|
255
|
+
modelName: string,
|
|
256
|
+
query: Dict<unknown> | undefined,
|
|
257
|
+
identifiers: StableRecordIdentifier[],
|
|
258
|
+
payload?: CollectionResourceDocument
|
|
259
|
+
): AdapterPopulatedRecordArray {
|
|
245
260
|
assert(
|
|
246
261
|
`recordArrayManger.createAdapterPopulatedRecordArray expects modelName not modelClass as the first param, received ${modelName}`,
|
|
247
262
|
typeof modelName === 'string'
|
|
248
263
|
);
|
|
249
264
|
|
|
250
|
-
let array;
|
|
265
|
+
let array: AdapterPopulatedRecordArray;
|
|
251
266
|
if (Array.isArray(identifiers)) {
|
|
252
267
|
array = AdapterPopulatedRecordArray.create({
|
|
253
268
|
modelName,
|
|
@@ -257,8 +272,11 @@ class RecordArrayManager {
|
|
|
257
272
|
manager: this,
|
|
258
273
|
isLoaded: true,
|
|
259
274
|
isUpdating: false,
|
|
260
|
-
|
|
261
|
-
links
|
|
275
|
+
// TODO this assign kills the root reference but a deep-copy would be required
|
|
276
|
+
// for both meta and links to actually not be by-ref. We whould likely change
|
|
277
|
+
// this to a dev-only deep-freeze.
|
|
278
|
+
meta: Object.assign({} as Meta, payload!.meta),
|
|
279
|
+
links: Object.assign({}, payload!.links),
|
|
262
280
|
});
|
|
263
281
|
|
|
264
282
|
this._associateWithRecordArray(identifiers, array);
|
|
@@ -266,7 +284,8 @@ class RecordArrayManager {
|
|
|
266
284
|
array = AdapterPopulatedRecordArray.create({
|
|
267
285
|
modelName,
|
|
268
286
|
query: query,
|
|
269
|
-
content: A(),
|
|
287
|
+
content: A<StableRecordIdentifier>(),
|
|
288
|
+
isLoaded: false,
|
|
270
289
|
store: this.store,
|
|
271
290
|
manager: this,
|
|
272
291
|
});
|
|
@@ -285,7 +304,7 @@ class RecordArrayManager {
|
|
|
285
304
|
@internal
|
|
286
305
|
@param {RecordArray} array
|
|
287
306
|
*/
|
|
288
|
-
unregisterRecordArray(array) {
|
|
307
|
+
unregisterRecordArray(array: RecordArray): void {
|
|
289
308
|
let modelName = array.modelName;
|
|
290
309
|
|
|
291
310
|
// remove from adapter populated record array
|
|
@@ -308,7 +327,7 @@ class RecordArrayManager {
|
|
|
308
327
|
* @param {StableIdentifier} identifiers
|
|
309
328
|
* @param {RecordArray} array
|
|
310
329
|
*/
|
|
311
|
-
_associateWithRecordArray(identifiers, array) {
|
|
330
|
+
_associateWithRecordArray(identifiers: StableRecordIdentifier[], array: RecordArray): void {
|
|
312
331
|
for (let i = 0, l = identifiers.length; i < l; i++) {
|
|
313
332
|
let identifier = identifiers[i];
|
|
314
333
|
identifier = getIdentifier(identifier);
|
|
@@ -321,7 +340,7 @@ class RecordArrayManager {
|
|
|
321
340
|
@method recordDidChange
|
|
322
341
|
@internal
|
|
323
342
|
*/
|
|
324
|
-
recordDidChange(identifier) {
|
|
343
|
+
recordDidChange(identifier: StableRecordIdentifier): void {
|
|
325
344
|
if (this.isDestroying || this.isDestroyed) {
|
|
326
345
|
return;
|
|
327
346
|
}
|
|
@@ -340,22 +359,26 @@ class RecordArrayManager {
|
|
|
340
359
|
return;
|
|
341
360
|
}
|
|
342
361
|
|
|
362
|
+
// TODO do we still need this schedule?
|
|
363
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
343
364
|
emberBackburner.schedule('actions', this, this._flush);
|
|
344
365
|
}
|
|
345
366
|
|
|
346
367
|
willDestroy() {
|
|
347
|
-
Object.keys(this._liveRecordArrays).forEach((modelName) => this._liveRecordArrays[modelName]
|
|
368
|
+
Object.keys(this._liveRecordArrays).forEach((modelName) => this._liveRecordArrays[modelName]!.destroy());
|
|
348
369
|
this._adapterPopulatedRecordArrays.forEach((entry) => entry.destroy());
|
|
349
370
|
this.isDestroyed = true;
|
|
350
371
|
}
|
|
351
372
|
|
|
352
373
|
destroy() {
|
|
353
374
|
this.isDestroying = true;
|
|
375
|
+
// TODO do we still need this schedule?
|
|
376
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
354
377
|
emberBackburner.schedule('actions', this, this.willDestroy);
|
|
355
378
|
}
|
|
356
379
|
}
|
|
357
380
|
|
|
358
|
-
function removeFromArray(array, item) {
|
|
381
|
+
function removeFromArray(array: RecordArray[], item: RecordArray): boolean {
|
|
359
382
|
let index = array.indexOf(item);
|
|
360
383
|
|
|
361
384
|
if (index !== -1) {
|
|
@@ -366,9 +389,13 @@ function removeFromArray(array, item) {
|
|
|
366
389
|
return false;
|
|
367
390
|
}
|
|
368
391
|
|
|
369
|
-
function updateLiveRecordArray(
|
|
370
|
-
|
|
371
|
-
|
|
392
|
+
function updateLiveRecordArray(
|
|
393
|
+
store: CoreStore,
|
|
394
|
+
recordArray: RecordArray,
|
|
395
|
+
identifiers: StableRecordIdentifier[]
|
|
396
|
+
): void {
|
|
397
|
+
let identifiersToAdd: StableRecordIdentifier[] = [];
|
|
398
|
+
let identifiersToRemove: StableRecordIdentifier[] = [];
|
|
372
399
|
|
|
373
400
|
for (let i = 0; i < identifiers.length; i++) {
|
|
374
401
|
let identifier = identifiers[i];
|
|
@@ -396,13 +423,13 @@ function updateLiveRecordArray(store, recordArray, identifiers) {
|
|
|
396
423
|
}
|
|
397
424
|
}
|
|
398
425
|
|
|
399
|
-
function removeFromAdapterPopulatedRecordArrays(store, identifiers) {
|
|
426
|
+
function removeFromAdapterPopulatedRecordArrays(store: CoreStore, identifiers: StableRecordIdentifier[]): void {
|
|
400
427
|
for (let i = 0; i < identifiers.length; i++) {
|
|
401
428
|
removeFromAll(store, identifiers[i]);
|
|
402
429
|
}
|
|
403
430
|
}
|
|
404
431
|
|
|
405
|
-
function removeFromAll(store, identifier) {
|
|
432
|
+
function removeFromAll(store: CoreStore, identifier: StableRecordIdentifier): void {
|
|
406
433
|
identifier = getIdentifier(identifier);
|
|
407
434
|
const recordArrays = recordArraysForIdentifier(identifier);
|
|
408
435
|
|