@ember-data/store 3.28.10 → 3.28.11
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.
|
@@ -2500,6 +2500,7 @@ abstract class CoreStore extends Service {
|
|
|
2500
2500
|
const factory = internalModelFactoryFor(this);
|
|
2501
2501
|
|
|
2502
2502
|
if (modelName === undefined) {
|
|
2503
|
+
this._notificationManager.destroy();
|
|
2503
2504
|
factory.clear();
|
|
2504
2505
|
} else {
|
|
2505
2506
|
let normalizedModelName = normalizeModelName(modelName);
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { assert } from '@ember/debug';
|
|
2
|
+
import { DEBUG } from '@glimmer/env';
|
|
3
|
+
|
|
4
|
+
import isStableIdentifier from '../identifiers/is-stable-identifier';
|
|
2
5
|
|
|
3
6
|
type CoreStore = import('./core-store').default;
|
|
4
|
-
type RecordIdentifier = import('../ts-interfaces/identifier').RecordIdentifier;
|
|
5
7
|
type StableRecordIdentifier = import('../ts-interfaces/identifier').StableRecordIdentifier;
|
|
6
8
|
|
|
7
|
-
type UnsubscribeToken =
|
|
9
|
+
type UnsubscribeToken = object;
|
|
10
|
+
let tokenId = 0;
|
|
8
11
|
|
|
9
|
-
const Cache = new
|
|
10
|
-
const Tokens = new
|
|
12
|
+
const Cache = new Map<StableRecordIdentifier, Map<UnsubscribeToken, NotificationCallback>>();
|
|
13
|
+
const Tokens = new Map<UnsubscribeToken, StableRecordIdentifier>();
|
|
11
14
|
|
|
12
15
|
export type NotificationType =
|
|
13
16
|
| 'attributes'
|
|
@@ -20,50 +23,73 @@ export type NotificationType =
|
|
|
20
23
|
| 'property'; // 'property' is an internal EmberData only transition period concept.
|
|
21
24
|
|
|
22
25
|
export interface NotificationCallback {
|
|
23
|
-
(identifier:
|
|
24
|
-
(identifier:
|
|
26
|
+
(identifier: StableRecordIdentifier, notificationType: 'attributes' | 'relationships', key?: string): void;
|
|
27
|
+
(identifier: StableRecordIdentifier, notificationType: 'errors' | 'meta' | 'identity' | 'state'): void;
|
|
25
28
|
(identifier: StableRecordIdentifier, notificationType: NotificationType, key?: string): void;
|
|
26
29
|
}
|
|
27
30
|
|
|
31
|
+
// TODO this isn't importable anyway, remove and use a map on the manager?
|
|
28
32
|
export function unsubscribe(token: UnsubscribeToken) {
|
|
29
33
|
let identifier = Tokens.get(token);
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
|
|
35
|
+
if (identifier) {
|
|
36
|
+
Tokens.delete(token);
|
|
37
|
+
const map = Cache.get(identifier);
|
|
38
|
+
map?.delete(token);
|
|
32
39
|
}
|
|
33
|
-
Tokens.delete(token);
|
|
34
|
-
const map = Cache.get(identifier);
|
|
35
|
-
map?.delete(token);
|
|
36
40
|
}
|
|
37
41
|
/*
|
|
38
42
|
Currently only support a single callback per identifier
|
|
39
43
|
*/
|
|
40
44
|
export default class NotificationManager {
|
|
41
|
-
|
|
45
|
+
declare store: CoreStore;
|
|
46
|
+
constructor(store: CoreStore) {
|
|
47
|
+
this.store = store;
|
|
48
|
+
}
|
|
42
49
|
|
|
43
|
-
subscribe(identifier:
|
|
44
|
-
|
|
45
|
-
let map = Cache.get(
|
|
46
|
-
|
|
50
|
+
subscribe(identifier: StableRecordIdentifier, callback: NotificationCallback): UnsubscribeToken {
|
|
51
|
+
assert(`Expected to receive a stable Identifier to subscribe to`, isStableIdentifier(identifier));
|
|
52
|
+
let map = Cache.get(identifier);
|
|
53
|
+
|
|
54
|
+
if (!map) {
|
|
47
55
|
map = new Map();
|
|
48
|
-
Cache.set(
|
|
56
|
+
Cache.set(identifier, map);
|
|
49
57
|
}
|
|
50
|
-
|
|
58
|
+
|
|
59
|
+
let unsubToken = DEBUG ? { _tokenRef: tokenId++ } : {};
|
|
51
60
|
map.set(unsubToken, callback);
|
|
52
|
-
Tokens.set(unsubToken,
|
|
61
|
+
Tokens.set(unsubToken, identifier);
|
|
53
62
|
return unsubToken;
|
|
54
63
|
}
|
|
55
64
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
65
|
+
unsubscribe(token: UnsubscribeToken) {
|
|
66
|
+
unsubscribe(token);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// deactivated type signature overloads because pass-through was failing to match any. Bring back if possible.
|
|
70
|
+
// notify(identifier: StableRecordIdentifier, value: 'attributes' | 'relationships', key?: string): boolean;
|
|
71
|
+
// notify(identifier: StableRecordIdentifier, value: 'errors' | 'meta' | 'identity' | 'state'): boolean;
|
|
72
|
+
notify(identifier: StableRecordIdentifier, value: NotificationType, key?: string): boolean {
|
|
73
|
+
assert(
|
|
74
|
+
`Notify does not accept a key argument for the namespace '${value}'. Received key '${key}'.`,
|
|
75
|
+
!key || value === 'attributes' || value === 'relationships'
|
|
76
|
+
);
|
|
77
|
+
if (!isStableIdentifier(identifier)) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let callbackMap = Cache.get(identifier);
|
|
61
82
|
if (!callbackMap || !callbackMap.size) {
|
|
62
83
|
return false;
|
|
63
84
|
}
|
|
64
85
|
callbackMap.forEach((cb) => {
|
|
65
|
-
cb(
|
|
86
|
+
cb(identifier, value, key);
|
|
66
87
|
});
|
|
67
88
|
return true;
|
|
68
89
|
}
|
|
90
|
+
|
|
91
|
+
destroy() {
|
|
92
|
+
Tokens.clear();
|
|
93
|
+
Cache.clear();
|
|
94
|
+
}
|
|
69
95
|
}
|
|
@@ -40,8 +40,8 @@ export default class BelongsToReference extends Reference {
|
|
|
40
40
|
declare parentIdentifier: StableRecordIdentifier;
|
|
41
41
|
|
|
42
42
|
// unsubscribe tokens given to us by the notification manager
|
|
43
|
-
#token!:
|
|
44
|
-
#relatedToken:
|
|
43
|
+
#token!: object;
|
|
44
|
+
#relatedToken: object | null = null;
|
|
45
45
|
|
|
46
46
|
@tracked _ref = 0;
|
|
47
47
|
|
|
@@ -76,8 +76,10 @@ export default class BelongsToReference extends Reference {
|
|
|
76
76
|
destroy() {
|
|
77
77
|
if (CUSTOM_MODEL_CLASS) {
|
|
78
78
|
unsubscribe(this.#token);
|
|
79
|
+
this.#token = null as unknown as object;
|
|
79
80
|
if (this.#relatedToken) {
|
|
80
81
|
unsubscribe(this.#relatedToken);
|
|
82
|
+
this.#relatedToken = null;
|
|
81
83
|
}
|
|
82
84
|
}
|
|
83
85
|
}
|
|
@@ -88,6 +90,7 @@ export default class BelongsToReference extends Reference {
|
|
|
88
90
|
this._ref; // consume the tracked prop
|
|
89
91
|
if (this.#relatedToken) {
|
|
90
92
|
unsubscribe(this.#relatedToken);
|
|
93
|
+
this.#relatedToken = null;
|
|
91
94
|
}
|
|
92
95
|
|
|
93
96
|
let resource = this._resource();
|
|
@@ -76,6 +76,7 @@ export default class HasManyReference extends Reference {
|
|
|
76
76
|
destroy() {
|
|
77
77
|
if (CUSTOM_MODEL_CLASS) {
|
|
78
78
|
unsubscribe(this.#token);
|
|
79
|
+
this.#token = null as unknown as object;
|
|
79
80
|
this.#relatedTokenMap.forEach((token) => {
|
|
80
81
|
unsubscribe(token);
|
|
81
82
|
});
|
|
@@ -90,22 +91,30 @@ export default class HasManyReference extends Reference {
|
|
|
90
91
|
|
|
91
92
|
let resource = this._resource();
|
|
92
93
|
|
|
93
|
-
this.#relatedTokenMap
|
|
94
|
-
|
|
95
|
-
});
|
|
96
|
-
this.#relatedTokenMap.clear();
|
|
94
|
+
let map = this.#relatedTokenMap;
|
|
95
|
+
this.#relatedTokenMap = new Map();
|
|
97
96
|
|
|
98
97
|
if (resource && resource.data) {
|
|
99
98
|
return resource.data.map((resourceIdentifier) => {
|
|
100
99
|
const identifier = this.store.identifierCache.getOrCreateRecordIdentifier(resourceIdentifier);
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
100
|
+
|
|
101
|
+
let token = map.get(identifier);
|
|
102
|
+
|
|
103
|
+
if (token) {
|
|
104
|
+
map.delete(identifier);
|
|
105
|
+
} else {
|
|
106
|
+
token = this.store._notificationManager.subscribe(
|
|
107
|
+
identifier,
|
|
108
|
+
(_: StableRecordIdentifier, bucket: NotificationType, notifiedKey?: string) => {
|
|
109
|
+
if (
|
|
110
|
+
bucket === 'identity' ||
|
|
111
|
+
((bucket === 'attributes' || bucket === 'property') && notifiedKey === 'id')
|
|
112
|
+
) {
|
|
113
|
+
this._ref++;
|
|
114
|
+
}
|
|
106
115
|
}
|
|
107
|
-
|
|
108
|
-
|
|
116
|
+
);
|
|
117
|
+
}
|
|
109
118
|
|
|
110
119
|
this.#relatedTokenMap.set(identifier, token);
|
|
111
120
|
|
|
@@ -113,6 +122,11 @@ export default class HasManyReference extends Reference {
|
|
|
113
122
|
});
|
|
114
123
|
}
|
|
115
124
|
|
|
125
|
+
map.forEach((token) => {
|
|
126
|
+
this.store._notificationManager.unsubscribe(token);
|
|
127
|
+
});
|
|
128
|
+
map.clear();
|
|
129
|
+
|
|
116
130
|
return [];
|
|
117
131
|
}
|
|
118
132
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ember-data/store",
|
|
3
|
-
"version": "3.28.
|
|
3
|
+
"version": "3.28.11",
|
|
4
4
|
"description": "The default blueprint for ember-cli addons.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ember-addon"
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"start": "ember serve"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@ember-data/canary-features": "3.28.
|
|
21
|
-
"@ember-data/private-build-infra": "3.28.
|
|
20
|
+
"@ember-data/canary-features": "3.28.11",
|
|
21
|
+
"@ember-data/private-build-infra": "3.28.11",
|
|
22
22
|
"@ember/string": "^3.0.0",
|
|
23
23
|
"@glimmer/tracking": "^1.0.4",
|
|
24
24
|
"ember-cached-decorator-polyfill": "^0.1.4",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"ember-cli-typescript": "^4.1.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@ember-data/unpublished-test-infra": "3.28.
|
|
30
|
+
"@ember-data/unpublished-test-infra": "3.28.11",
|
|
31
31
|
"@ember/optional-features": "^2.0.0",
|
|
32
32
|
"@ember/test-helpers": "^2.2.5",
|
|
33
33
|
"@types/ember": "^3.16.5",
|