@ember-data/store 5.2.0-alpha.5 → 5.2.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.
- package/addon/-private.js +275 -237
- package/addon/-private.js.map +1 -1
- package/addon-main.js +1 -1
- package/package.json +11 -11
package/addon/-private.js
CHANGED
|
@@ -1062,205 +1062,11 @@ function detectMerge(typesCache, identifier, data, newId, lids) {
|
|
|
1062
1062
|
}
|
|
1063
1063
|
return false;
|
|
1064
1064
|
}
|
|
1065
|
-
|
|
1066
|
-
const CacheOperations = new Set(['added', 'removed', 'state', 'updated']);
|
|
1067
|
-
function isCacheOperationValue(value) {
|
|
1068
|
-
return CacheOperations.has(value);
|
|
1069
|
-
}
|
|
1070
|
-
function runLoopIsFlushing() {
|
|
1071
|
-
//@ts-expect-error
|
|
1072
|
-
return !!_backburner.currentInstance && _backburner._autorun !== true;
|
|
1073
|
-
}
|
|
1074
|
-
const Cache = new Map();
|
|
1075
|
-
const Tokens = new Map();
|
|
1076
|
-
// TODO this isn't importable anyway, remove and use a map on the manager?
|
|
1077
|
-
function unsubscribe(token) {
|
|
1078
|
-
let identifier = Tokens.get(token);
|
|
1079
|
-
if (macroCondition(getOwnConfig().debug.LOG_NOTIFICATIONS)) {
|
|
1080
|
-
if (!identifier) {
|
|
1081
|
-
// eslint-disable-next-line no-console
|
|
1082
|
-
console.log('Passed unknown unsubscribe token to unsubscribe', identifier);
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
if (identifier) {
|
|
1086
|
-
Tokens.delete(token);
|
|
1087
|
-
const map = Cache.get(identifier);
|
|
1088
|
-
map?.delete(token);
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1065
|
+
var _class$1, _descriptor$1;
|
|
1091
1066
|
|
|
1092
1067
|
/**
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
*
|
|
1096
|
-
* This Feature is what allows EmberData to create subscriptions that
|
|
1097
|
-
* work with any framework or change-notification system.
|
|
1098
|
-
*
|
|
1099
|
-
* @class NotificationManager
|
|
1100
|
-
* @public
|
|
1101
|
-
*/
|
|
1102
|
-
class NotificationManager {
|
|
1103
|
-
constructor(store) {
|
|
1104
|
-
this.store = store;
|
|
1105
|
-
this.isDestroyed = false;
|
|
1106
|
-
this._buffered = new Map();
|
|
1107
|
-
this._hasFlush = false;
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
/**
|
|
1111
|
-
* Subscribe to changes for a given resource identifier, resource addition/removal, or document addition/removal.
|
|
1112
|
-
*
|
|
1113
|
-
* ```ts
|
|
1114
|
-
* export type CacheOperation = 'added' | 'removed' | 'updated' | 'state';
|
|
1115
|
-
*
|
|
1116
|
-
* export interface NotificationCallback {
|
|
1117
|
-
* (identifier: StableRecordIdentifier, notificationType: 'attributes' | 'relationships', key?: string): void;
|
|
1118
|
-
* (identifier: StableRecordIdentifier, notificationType: 'errors' | 'meta' | 'identity' | 'state'): void;
|
|
1119
|
-
* (identifier: StableRecordIdentifier, notificationType: NotificationType, key?: string): void;
|
|
1120
|
-
* }
|
|
1121
|
-
* export interface ResourceOperationCallback {
|
|
1122
|
-
* // resource updates
|
|
1123
|
-
* (identifier: StableRecordIdentifier, notificationType: CacheOperation): void;
|
|
1124
|
-
* }
|
|
1125
|
-
* export interface DocumentOperationCallback {
|
|
1126
|
-
* // document updates
|
|
1127
|
-
* (identifier: StableDocumentIdentifier, notificationType: CacheOperation): void;
|
|
1128
|
-
* }
|
|
1129
|
-
* ```
|
|
1130
|
-
*
|
|
1131
|
-
* @method subscribe
|
|
1132
|
-
* @public
|
|
1133
|
-
* @param {StableDocumentIdentifier | StableRecordIdentifier | 'resource' | 'document'} identifier
|
|
1134
|
-
* @param {NotificationCallback | ResourceOperationCallback | DocumentOperationCallback} callback
|
|
1135
|
-
* @returns {UnsubscribeToken} an opaque token to be used with unsubscribe
|
|
1136
|
-
*/
|
|
1137
|
-
|
|
1138
|
-
subscribe(identifier, callback) {
|
|
1139
|
-
assert(`Expected to receive a stable Identifier to subscribe to`, identifier === 'resource' || identifier === 'document' || isStableIdentifier(identifier) || isDocumentIdentifier(identifier));
|
|
1140
|
-
let map = Cache.get(identifier);
|
|
1141
|
-
if (!map) {
|
|
1142
|
-
map = new Map();
|
|
1143
|
-
Cache.set(identifier, map);
|
|
1144
|
-
}
|
|
1145
|
-
let unsubToken = macroCondition(getOwnConfig().env.DEBUG) ? {
|
|
1146
|
-
_tokenRef: tokenId++
|
|
1147
|
-
} : {};
|
|
1148
|
-
map.set(unsubToken, callback);
|
|
1149
|
-
Tokens.set(unsubToken, identifier);
|
|
1150
|
-
return unsubToken;
|
|
1151
|
-
}
|
|
1152
|
-
|
|
1153
|
-
/**
|
|
1154
|
-
* remove a previous subscription
|
|
1155
|
-
*
|
|
1156
|
-
* @method unsubscribe
|
|
1157
|
-
* @public
|
|
1158
|
-
* @param {UnsubscribeToken} token
|
|
1159
|
-
*/
|
|
1160
|
-
unsubscribe(token) {
|
|
1161
|
-
if (!this.isDestroyed) {
|
|
1162
|
-
unsubscribe(token);
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1166
|
-
/**
|
|
1167
|
-
* Custom Caches and Application Code should not call this method directly.
|
|
1168
|
-
*
|
|
1169
|
-
* @method notify
|
|
1170
|
-
* @param identifier
|
|
1171
|
-
* @param value
|
|
1172
|
-
* @param key
|
|
1173
|
-
* @return {Boolean} whether a notification was delivered to any subscribers
|
|
1174
|
-
* @private
|
|
1175
|
-
*/
|
|
1176
|
-
|
|
1177
|
-
notify(identifier, value, key) {
|
|
1178
|
-
assert(`Notify does not accept a key argument for the namespace '${value}'. Received key '${key || ''}'.`, !key || value === 'attributes' || value === 'relationships');
|
|
1179
|
-
if (!isStableIdentifier(identifier) && !isDocumentIdentifier(identifier)) {
|
|
1180
|
-
if (macroCondition(getOwnConfig().debug.LOG_NOTIFICATIONS)) {
|
|
1181
|
-
// eslint-disable-next-line no-console
|
|
1182
|
-
console.log(`Notifying: Expected to receive a stable Identifier to notify '${value}' '${key || ''}' with, but ${String(identifier)} is not in the cache`, identifier);
|
|
1183
|
-
}
|
|
1184
|
-
return false;
|
|
1185
|
-
}
|
|
1186
|
-
if (macroCondition(getOwnConfig().debug.LOG_NOTIFICATIONS)) {
|
|
1187
|
-
// eslint-disable-next-line no-console
|
|
1188
|
-
console.log(`Buffering Notify: ${String(identifier.lid)}\t${value}\t${key || ''}`);
|
|
1189
|
-
}
|
|
1190
|
-
const hasSubscribers = Boolean(Cache.get(identifier)?.size);
|
|
1191
|
-
if (isCacheOperationValue(value) || hasSubscribers) {
|
|
1192
|
-
let buffer = this._buffered.get(identifier);
|
|
1193
|
-
if (!buffer) {
|
|
1194
|
-
buffer = [];
|
|
1195
|
-
this._buffered.set(identifier, buffer);
|
|
1196
|
-
}
|
|
1197
|
-
buffer.push([value, key]);
|
|
1198
|
-
void this._scheduleNotify();
|
|
1199
|
-
}
|
|
1200
|
-
return hasSubscribers;
|
|
1201
|
-
}
|
|
1202
|
-
_onNextFlush(cb) {
|
|
1203
|
-
this._onFlushCB = cb;
|
|
1204
|
-
}
|
|
1205
|
-
_scheduleNotify() {
|
|
1206
|
-
const asyncFlush = this.store._enableAsyncFlush;
|
|
1207
|
-
if (this._hasFlush) {
|
|
1208
|
-
if (asyncFlush !== false && !runLoopIsFlushing()) {
|
|
1209
|
-
return;
|
|
1210
|
-
}
|
|
1211
|
-
}
|
|
1212
|
-
if (asyncFlush && !runLoopIsFlushing()) {
|
|
1213
|
-
this._hasFlush = true;
|
|
1214
|
-
return;
|
|
1215
|
-
}
|
|
1216
|
-
this._flush();
|
|
1217
|
-
}
|
|
1218
|
-
_flush() {
|
|
1219
|
-
if (this._buffered.size) {
|
|
1220
|
-
this._buffered.forEach((states, identifier) => {
|
|
1221
|
-
states.forEach(args => {
|
|
1222
|
-
// @ts-expect-error
|
|
1223
|
-
this._flushNotification(identifier, args[0], args[1]);
|
|
1224
|
-
});
|
|
1225
|
-
});
|
|
1226
|
-
this._buffered = new Map();
|
|
1227
|
-
}
|
|
1228
|
-
this._hasFlush = false;
|
|
1229
|
-
this._onFlushCB?.();
|
|
1230
|
-
this._onFlushCB = undefined;
|
|
1231
|
-
}
|
|
1232
|
-
_flushNotification(identifier, value, key) {
|
|
1233
|
-
if (macroCondition(getOwnConfig().debug.LOG_NOTIFICATIONS)) {
|
|
1234
|
-
// eslint-disable-next-line no-console
|
|
1235
|
-
console.log(`Notifying: ${String(identifier)}\t${value}\t${key || ''}`);
|
|
1236
|
-
}
|
|
1237
|
-
|
|
1238
|
-
// TODO for documents this will need to switch based on Identifier kind
|
|
1239
|
-
if (isCacheOperationValue(value)) {
|
|
1240
|
-
let callbackMap = Cache.get(isDocumentIdentifier(identifier) ? 'document' : 'resource');
|
|
1241
|
-
if (callbackMap) {
|
|
1242
|
-
callbackMap.forEach(cb => {
|
|
1243
|
-
cb(identifier, value);
|
|
1244
|
-
});
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
let callbackMap = Cache.get(identifier);
|
|
1248
|
-
if (!callbackMap || !callbackMap.size) {
|
|
1249
|
-
return false;
|
|
1250
|
-
}
|
|
1251
|
-
callbackMap.forEach(cb => {
|
|
1252
|
-
// @ts-expect-error overload doesn't narrow within body
|
|
1253
|
-
cb(identifier, value, key);
|
|
1254
|
-
});
|
|
1255
|
-
return true;
|
|
1256
|
-
}
|
|
1257
|
-
destroy() {
|
|
1258
|
-
this.isDestroyed = true;
|
|
1259
|
-
Tokens.clear();
|
|
1260
|
-
Cache.clear();
|
|
1261
|
-
}
|
|
1262
|
-
}
|
|
1263
|
-
var _class$1, _descriptor$1;
|
|
1068
|
+
@module @ember-data/store
|
|
1069
|
+
*/
|
|
1264
1070
|
/**
|
|
1265
1071
|
@module @ember-data/store
|
|
1266
1072
|
*/
|
|
@@ -1288,7 +1094,7 @@ let RecordReference = (_class$1 = class RecordReference {
|
|
|
1288
1094
|
});
|
|
1289
1095
|
}
|
|
1290
1096
|
destroy() {
|
|
1291
|
-
unsubscribe(this.___token);
|
|
1097
|
+
this.store.notifications.unsubscribe(this.___token);
|
|
1292
1098
|
}
|
|
1293
1099
|
get type() {
|
|
1294
1100
|
return this.identifier().type;
|
|
@@ -2555,6 +2361,203 @@ class CacheManager {
|
|
|
2555
2361
|
return _classPrivateFieldBase(this, _cache)[_cache].isDeletionCommitted(identifier);
|
|
2556
2362
|
}
|
|
2557
2363
|
}
|
|
2364
|
+
let tokenId = 0;
|
|
2365
|
+
const CacheOperations = new Set(['added', 'removed', 'state', 'updated']);
|
|
2366
|
+
function isCacheOperationValue(value) {
|
|
2367
|
+
return CacheOperations.has(value);
|
|
2368
|
+
}
|
|
2369
|
+
function runLoopIsFlushing() {
|
|
2370
|
+
//@ts-expect-error
|
|
2371
|
+
return !!_backburner.currentInstance && _backburner._autorun !== true;
|
|
2372
|
+
}
|
|
2373
|
+
function _unsubscribe(tokens, token, cache) {
|
|
2374
|
+
let identifier = tokens.get(token);
|
|
2375
|
+
if (macroCondition(getOwnConfig().debug.LOG_NOTIFICATIONS)) {
|
|
2376
|
+
if (!identifier) {
|
|
2377
|
+
// eslint-disable-next-line no-console
|
|
2378
|
+
console.log('Passed unknown unsubscribe token to unsubscribe', identifier);
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
if (identifier) {
|
|
2382
|
+
tokens.delete(token);
|
|
2383
|
+
const map = cache.get(identifier);
|
|
2384
|
+
map?.delete(token);
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
|
|
2388
|
+
/**
|
|
2389
|
+
* The NotificationManager provides the ability to subscribe to
|
|
2390
|
+
* changes to Cache state.
|
|
2391
|
+
*
|
|
2392
|
+
* This Feature is what allows EmberData to create subscriptions that
|
|
2393
|
+
* work with any framework or change-notification system.
|
|
2394
|
+
*
|
|
2395
|
+
* @class NotificationManager
|
|
2396
|
+
* @public
|
|
2397
|
+
*/
|
|
2398
|
+
class NotificationManager {
|
|
2399
|
+
constructor(store) {
|
|
2400
|
+
this.store = store;
|
|
2401
|
+
this.isDestroyed = false;
|
|
2402
|
+
this._buffered = new Map();
|
|
2403
|
+
this._hasFlush = false;
|
|
2404
|
+
this._cache = new Map();
|
|
2405
|
+
this._tokens = new Map();
|
|
2406
|
+
}
|
|
2407
|
+
|
|
2408
|
+
/**
|
|
2409
|
+
* Subscribe to changes for a given resource identifier, resource addition/removal, or document addition/removal.
|
|
2410
|
+
*
|
|
2411
|
+
* ```ts
|
|
2412
|
+
* export type CacheOperation = 'added' | 'removed' | 'updated' | 'state';
|
|
2413
|
+
*
|
|
2414
|
+
* export interface NotificationCallback {
|
|
2415
|
+
* (identifier: StableRecordIdentifier, notificationType: 'attributes' | 'relationships', key?: string): void;
|
|
2416
|
+
* (identifier: StableRecordIdentifier, notificationType: 'errors' | 'meta' | 'identity' | 'state'): void;
|
|
2417
|
+
* (identifier: StableRecordIdentifier, notificationType: NotificationType, key?: string): void;
|
|
2418
|
+
* }
|
|
2419
|
+
* export interface ResourceOperationCallback {
|
|
2420
|
+
* // resource updates
|
|
2421
|
+
* (identifier: StableRecordIdentifier, notificationType: CacheOperation): void;
|
|
2422
|
+
* }
|
|
2423
|
+
* export interface DocumentOperationCallback {
|
|
2424
|
+
* // document updates
|
|
2425
|
+
* (identifier: StableDocumentIdentifier, notificationType: CacheOperation): void;
|
|
2426
|
+
* }
|
|
2427
|
+
* ```
|
|
2428
|
+
*
|
|
2429
|
+
* @method subscribe
|
|
2430
|
+
* @public
|
|
2431
|
+
* @param {StableDocumentIdentifier | StableRecordIdentifier | 'resource' | 'document'} identifier
|
|
2432
|
+
* @param {NotificationCallback | ResourceOperationCallback | DocumentOperationCallback} callback
|
|
2433
|
+
* @returns {UnsubscribeToken} an opaque token to be used with unsubscribe
|
|
2434
|
+
*/
|
|
2435
|
+
|
|
2436
|
+
subscribe(identifier, callback) {
|
|
2437
|
+
assert(`Expected to receive a stable Identifier to subscribe to`, identifier === 'resource' || identifier === 'document' || isStableIdentifier(identifier) || isDocumentIdentifier(identifier));
|
|
2438
|
+
let map = this._cache.get(identifier);
|
|
2439
|
+
if (!map) {
|
|
2440
|
+
map = new Map();
|
|
2441
|
+
this._cache.set(identifier, map);
|
|
2442
|
+
}
|
|
2443
|
+
let unsubToken = macroCondition(getOwnConfig().env.DEBUG) ? {
|
|
2444
|
+
_tokenRef: tokenId++
|
|
2445
|
+
} : {};
|
|
2446
|
+
map.set(unsubToken, callback);
|
|
2447
|
+
this._tokens.set(unsubToken, identifier);
|
|
2448
|
+
return unsubToken;
|
|
2449
|
+
}
|
|
2450
|
+
|
|
2451
|
+
/**
|
|
2452
|
+
* remove a previous subscription
|
|
2453
|
+
*
|
|
2454
|
+
* @method unsubscribe
|
|
2455
|
+
* @public
|
|
2456
|
+
* @param {UnsubscribeToken} token
|
|
2457
|
+
*/
|
|
2458
|
+
unsubscribe(token) {
|
|
2459
|
+
if (!this.isDestroyed) {
|
|
2460
|
+
_unsubscribe(this._tokens, token, this._cache);
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
|
|
2464
|
+
/**
|
|
2465
|
+
* Custom Caches and Application Code should not call this method directly.
|
|
2466
|
+
*
|
|
2467
|
+
* @method notify
|
|
2468
|
+
* @param identifier
|
|
2469
|
+
* @param value
|
|
2470
|
+
* @param key
|
|
2471
|
+
* @return {Boolean} whether a notification was delivered to any subscribers
|
|
2472
|
+
* @private
|
|
2473
|
+
*/
|
|
2474
|
+
|
|
2475
|
+
notify(identifier, value, key) {
|
|
2476
|
+
assert(`Notify does not accept a key argument for the namespace '${value}'. Received key '${key || ''}'.`, !key || value === 'attributes' || value === 'relationships');
|
|
2477
|
+
if (!isStableIdentifier(identifier) && !isDocumentIdentifier(identifier)) {
|
|
2478
|
+
if (macroCondition(getOwnConfig().debug.LOG_NOTIFICATIONS)) {
|
|
2479
|
+
// eslint-disable-next-line no-console
|
|
2480
|
+
console.log(`Notifying: Expected to receive a stable Identifier to notify '${value}' '${key || ''}' with, but ${String(identifier)} is not in the cache`, identifier);
|
|
2481
|
+
}
|
|
2482
|
+
return false;
|
|
2483
|
+
}
|
|
2484
|
+
if (macroCondition(getOwnConfig().debug.LOG_NOTIFICATIONS)) {
|
|
2485
|
+
// eslint-disable-next-line no-console
|
|
2486
|
+
console.log(`Buffering Notify: ${String(identifier.lid)}\t${value}\t${key || ''}`);
|
|
2487
|
+
}
|
|
2488
|
+
const hasSubscribers = Boolean(this._cache.get(identifier)?.size);
|
|
2489
|
+
if (isCacheOperationValue(value) || hasSubscribers) {
|
|
2490
|
+
let buffer = this._buffered.get(identifier);
|
|
2491
|
+
if (!buffer) {
|
|
2492
|
+
buffer = [];
|
|
2493
|
+
this._buffered.set(identifier, buffer);
|
|
2494
|
+
}
|
|
2495
|
+
buffer.push([value, key]);
|
|
2496
|
+
void this._scheduleNotify();
|
|
2497
|
+
}
|
|
2498
|
+
return hasSubscribers;
|
|
2499
|
+
}
|
|
2500
|
+
_onNextFlush(cb) {
|
|
2501
|
+
this._onFlushCB = cb;
|
|
2502
|
+
}
|
|
2503
|
+
_scheduleNotify() {
|
|
2504
|
+
const asyncFlush = this.store._enableAsyncFlush;
|
|
2505
|
+
if (this._hasFlush) {
|
|
2506
|
+
if (asyncFlush !== false && !runLoopIsFlushing()) {
|
|
2507
|
+
return;
|
|
2508
|
+
}
|
|
2509
|
+
}
|
|
2510
|
+
if (asyncFlush && !runLoopIsFlushing()) {
|
|
2511
|
+
this._hasFlush = true;
|
|
2512
|
+
return;
|
|
2513
|
+
}
|
|
2514
|
+
this._flush();
|
|
2515
|
+
}
|
|
2516
|
+
_flush() {
|
|
2517
|
+
if (this._buffered.size) {
|
|
2518
|
+
this._buffered.forEach((states, identifier) => {
|
|
2519
|
+
states.forEach(args => {
|
|
2520
|
+
// @ts-expect-error
|
|
2521
|
+
this._flushNotification(identifier, args[0], args[1]);
|
|
2522
|
+
});
|
|
2523
|
+
});
|
|
2524
|
+
this._buffered = new Map();
|
|
2525
|
+
}
|
|
2526
|
+
this._hasFlush = false;
|
|
2527
|
+
this._onFlushCB?.();
|
|
2528
|
+
this._onFlushCB = undefined;
|
|
2529
|
+
}
|
|
2530
|
+
_flushNotification(identifier, value, key) {
|
|
2531
|
+
if (macroCondition(getOwnConfig().debug.LOG_NOTIFICATIONS)) {
|
|
2532
|
+
// eslint-disable-next-line no-console
|
|
2533
|
+
console.log(`Notifying: ${String(identifier)}\t${value}\t${key || ''}`);
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
// TODO for documents this will need to switch based on Identifier kind
|
|
2537
|
+
if (isCacheOperationValue(value)) {
|
|
2538
|
+
let callbackMap = this._cache.get(isDocumentIdentifier(identifier) ? 'document' : 'resource');
|
|
2539
|
+
if (callbackMap) {
|
|
2540
|
+
callbackMap.forEach(cb => {
|
|
2541
|
+
cb(identifier, value);
|
|
2542
|
+
});
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2545
|
+
let callbackMap = this._cache.get(identifier);
|
|
2546
|
+
if (!callbackMap || !callbackMap.size) {
|
|
2547
|
+
return false;
|
|
2548
|
+
}
|
|
2549
|
+
callbackMap.forEach(cb => {
|
|
2550
|
+
// @ts-expect-error overload doesn't narrow within body
|
|
2551
|
+
cb(identifier, value, key);
|
|
2552
|
+
});
|
|
2553
|
+
return true;
|
|
2554
|
+
}
|
|
2555
|
+
destroy() {
|
|
2556
|
+
this.isDestroyed = true;
|
|
2557
|
+
this._tokens.clear();
|
|
2558
|
+
this._cache.clear();
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2558
2561
|
var _class, _descriptor, _class3, _descriptor2;
|
|
2559
2562
|
const ARRAY_GETTER_METHODS = new Set([Symbol.iterator, 'concat', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'flat', 'flatMap', 'forEach', 'includes', 'indexOf', 'join', 'keys', 'lastIndexOf', 'map', 'reduce', 'reduceRight', 'slice', 'some', 'values']);
|
|
2560
2563
|
const ARRAY_SETTER_METHODS = new Set(['push', 'pop', 'unshift', 'shift', 'splice', 'sort']);
|
|
@@ -2661,13 +2664,13 @@ let IdentifierArray = (_class3 = class IdentifierArray {
|
|
|
2661
2664
|
@type Store
|
|
2662
2665
|
*/
|
|
2663
2666
|
|
|
2664
|
-
destroy() {
|
|
2665
|
-
this.isDestroying =
|
|
2667
|
+
destroy(clear) {
|
|
2668
|
+
this.isDestroying = !clear;
|
|
2666
2669
|
// changing the reference breaks the Proxy
|
|
2667
2670
|
// this[SOURCE] = [];
|
|
2668
2671
|
this[SOURCE].length = 0;
|
|
2669
2672
|
this[NOTIFY]();
|
|
2670
|
-
this.isDestroyed =
|
|
2673
|
+
this.isDestroyed = !clear;
|
|
2671
2674
|
}
|
|
2672
2675
|
|
|
2673
2676
|
// length must be on self for proxied methods to work properly
|
|
@@ -2958,8 +2961,8 @@ class Collection extends IdentifierArray {
|
|
|
2958
2961
|
});
|
|
2959
2962
|
return promise;
|
|
2960
2963
|
}
|
|
2961
|
-
destroy() {
|
|
2962
|
-
super.destroy();
|
|
2964
|
+
destroy(clear) {
|
|
2965
|
+
super.destroy(clear);
|
|
2963
2966
|
this._manager._managed.delete(this);
|
|
2964
2967
|
this._manager._pending.delete(this);
|
|
2965
2968
|
}
|
|
@@ -2991,7 +2994,6 @@ function extractIdentifierFromRecord$1(record) {
|
|
|
2991
2994
|
@module @ember-data/store
|
|
2992
2995
|
*/
|
|
2993
2996
|
|
|
2994
|
-
const RecordArraysCache = new Map();
|
|
2995
2997
|
const FAKE_ARR = {};
|
|
2996
2998
|
const SLICE_BATCH_SIZE = 1200;
|
|
2997
2999
|
/**
|
|
@@ -3057,11 +3059,15 @@ class RecordArrayManager {
|
|
|
3057
3059
|
this._pending = new Map();
|
|
3058
3060
|
this._staged = new Map();
|
|
3059
3061
|
this._keyedArrays = new Map();
|
|
3060
|
-
this._identifiers =
|
|
3062
|
+
this._identifiers = new Map();
|
|
3063
|
+
this._set = new Map();
|
|
3064
|
+
this._visibilitySet = new Map();
|
|
3061
3065
|
this._subscription = this.store.notifications.subscribe('resource', (identifier, type) => {
|
|
3062
3066
|
if (type === 'added') {
|
|
3067
|
+
this._visibilitySet.set(identifier, true);
|
|
3063
3068
|
this.identifierAdded(identifier);
|
|
3064
3069
|
} else if (type === 'removed') {
|
|
3070
|
+
this._visibilitySet.set(identifier, false);
|
|
3065
3071
|
this.identifierRemoved(identifier);
|
|
3066
3072
|
} else if (type === 'state') {
|
|
3067
3073
|
this.identifierChanged(identifier);
|
|
@@ -3073,7 +3079,7 @@ class RecordArrayManager {
|
|
|
3073
3079
|
if (!pending || this.isDestroying || this.isDestroyed) {
|
|
3074
3080
|
return;
|
|
3075
3081
|
}
|
|
3076
|
-
sync(array, pending);
|
|
3082
|
+
sync(array, pending, this._set.get(array));
|
|
3077
3083
|
this._pending.delete(array);
|
|
3078
3084
|
}
|
|
3079
3085
|
|
|
@@ -3106,6 +3112,7 @@ class RecordArrayManager {
|
|
|
3106
3112
|
manager: this
|
|
3107
3113
|
});
|
|
3108
3114
|
this._live.set(type, array);
|
|
3115
|
+
this._set.set(array, new Set(identifiers));
|
|
3109
3116
|
}
|
|
3110
3117
|
return array;
|
|
3111
3118
|
}
|
|
@@ -3123,8 +3130,9 @@ class RecordArrayManager {
|
|
|
3123
3130
|
};
|
|
3124
3131
|
let array = new Collection(options);
|
|
3125
3132
|
this._managed.add(array);
|
|
3133
|
+
this._set.set(array, new Set(options.identifiers || []));
|
|
3126
3134
|
if (config.identifiers) {
|
|
3127
|
-
associate(array, config.identifiers);
|
|
3135
|
+
associate(this._identifiers, array, config.identifiers);
|
|
3128
3136
|
}
|
|
3129
3137
|
return array;
|
|
3130
3138
|
}
|
|
@@ -3148,7 +3156,7 @@ class RecordArrayManager {
|
|
|
3148
3156
|
const allPending = this._pending;
|
|
3149
3157
|
let pending = new Map();
|
|
3150
3158
|
if (includeManaged) {
|
|
3151
|
-
let managed =
|
|
3159
|
+
let managed = this._identifiers.get(identifier);
|
|
3152
3160
|
if (managed) {
|
|
3153
3161
|
managed.forEach(arr => {
|
|
3154
3162
|
let changes = allPending.get(arr);
|
|
@@ -3194,12 +3202,13 @@ class RecordArrayManager {
|
|
|
3194
3202
|
const old = source.slice();
|
|
3195
3203
|
source.length = 0;
|
|
3196
3204
|
fastPush(source, identifiers);
|
|
3205
|
+
this._set.set(array, new Set(identifiers));
|
|
3197
3206
|
notifyArray(array);
|
|
3198
3207
|
array.meta = payload.meta || null;
|
|
3199
3208
|
array.links = payload.links || null;
|
|
3200
3209
|
array.isLoaded = true;
|
|
3201
|
-
disassociate(array, old);
|
|
3202
|
-
associate(array, identifiers);
|
|
3210
|
+
disassociate(this._identifiers, array, old);
|
|
3211
|
+
associate(this._identifiers, array, identifiers);
|
|
3203
3212
|
}
|
|
3204
3213
|
identifierAdded(identifier) {
|
|
3205
3214
|
let changeSets = this._getPendingFor(identifier, false);
|
|
@@ -3231,62 +3240,72 @@ class RecordArrayManager {
|
|
|
3231
3240
|
}
|
|
3232
3241
|
identifierChanged(identifier) {
|
|
3233
3242
|
let newState = this.store._instanceCache.recordIsLoaded(identifier, true);
|
|
3243
|
+
|
|
3244
|
+
// if the change matches the most recent direct added/removed
|
|
3245
|
+
// state, then we can ignore it
|
|
3246
|
+
if (this._visibilitySet.get(identifier) === newState) {
|
|
3247
|
+
return;
|
|
3248
|
+
}
|
|
3234
3249
|
if (newState) {
|
|
3235
3250
|
this.identifierAdded(identifier);
|
|
3236
3251
|
} else {
|
|
3237
3252
|
this.identifierRemoved(identifier);
|
|
3238
3253
|
}
|
|
3239
3254
|
}
|
|
3240
|
-
clear() {
|
|
3241
|
-
this._live.forEach(array => array.destroy());
|
|
3242
|
-
this._managed.forEach(array => array.destroy());
|
|
3255
|
+
clear(isClear = true) {
|
|
3256
|
+
this._live.forEach(array => array.destroy(isClear));
|
|
3257
|
+
this._managed.forEach(array => array.destroy(isClear));
|
|
3243
3258
|
this._managed.clear();
|
|
3244
|
-
|
|
3259
|
+
this._identifiers.clear();
|
|
3260
|
+
this._pending.clear();
|
|
3261
|
+
this._set.forEach(set => set.clear());
|
|
3262
|
+
this._visibilitySet.clear();
|
|
3245
3263
|
}
|
|
3246
3264
|
destroy() {
|
|
3247
3265
|
this.isDestroying = true;
|
|
3248
|
-
this.clear();
|
|
3266
|
+
this.clear(false);
|
|
3249
3267
|
this._live.clear();
|
|
3250
3268
|
this.isDestroyed = true;
|
|
3251
3269
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
3252
3270
|
this.store.notifications.unsubscribe(this._subscription);
|
|
3253
3271
|
}
|
|
3254
3272
|
}
|
|
3255
|
-
function associate(array, identifiers) {
|
|
3273
|
+
function associate(ArraysCache, array, identifiers) {
|
|
3256
3274
|
for (let i = 0; i < identifiers.length; i++) {
|
|
3257
3275
|
let identifier = identifiers[i];
|
|
3258
|
-
let cache =
|
|
3276
|
+
let cache = ArraysCache.get(identifier);
|
|
3259
3277
|
if (!cache) {
|
|
3260
3278
|
cache = new Set();
|
|
3261
|
-
|
|
3279
|
+
ArraysCache.set(identifier, cache);
|
|
3262
3280
|
}
|
|
3263
3281
|
cache.add(array);
|
|
3264
3282
|
}
|
|
3265
3283
|
}
|
|
3266
|
-
function disassociate(array, identifiers) {
|
|
3284
|
+
function disassociate(ArraysCache, array, identifiers) {
|
|
3267
3285
|
for (let i = 0; i < identifiers.length; i++) {
|
|
3268
|
-
disassociateIdentifier(array, identifiers[i]);
|
|
3286
|
+
disassociateIdentifier(ArraysCache, array, identifiers[i]);
|
|
3269
3287
|
}
|
|
3270
3288
|
}
|
|
3271
|
-
function disassociateIdentifier(array, identifier) {
|
|
3272
|
-
let cache =
|
|
3289
|
+
function disassociateIdentifier(ArraysCache, array, identifier) {
|
|
3290
|
+
let cache = ArraysCache.get(identifier);
|
|
3273
3291
|
if (cache) {
|
|
3274
3292
|
cache.delete(array);
|
|
3275
3293
|
}
|
|
3276
3294
|
}
|
|
3277
|
-
function sync(array, changes) {
|
|
3295
|
+
function sync(array, changes, arraySet) {
|
|
3278
3296
|
let state = array[SOURCE];
|
|
3279
3297
|
const adds = [];
|
|
3280
3298
|
const removes = [];
|
|
3281
3299
|
changes.forEach((value, key) => {
|
|
3282
3300
|
if (value === 'add') {
|
|
3283
3301
|
// likely we want to keep a Set along-side
|
|
3284
|
-
if (
|
|
3302
|
+
if (arraySet.has(key)) {
|
|
3285
3303
|
return;
|
|
3286
3304
|
}
|
|
3287
3305
|
adds.push(key);
|
|
3306
|
+
arraySet.add(key);
|
|
3288
3307
|
} else {
|
|
3289
|
-
if (
|
|
3308
|
+
if (arraySet.has(key)) {
|
|
3290
3309
|
removes.push(key);
|
|
3291
3310
|
}
|
|
3292
3311
|
}
|
|
@@ -3294,6 +3313,7 @@ function sync(array, changes) {
|
|
|
3294
3313
|
if (removes.length) {
|
|
3295
3314
|
if (removes.length === state.length) {
|
|
3296
3315
|
state.length = 0;
|
|
3316
|
+
arraySet.clear();
|
|
3297
3317
|
// changing the reference breaks the Proxy
|
|
3298
3318
|
// state = array[SOURCE] = [];
|
|
3299
3319
|
} else {
|
|
@@ -3301,6 +3321,7 @@ function sync(array, changes) {
|
|
|
3301
3321
|
const index = state.indexOf(i);
|
|
3302
3322
|
if (index !== -1) {
|
|
3303
3323
|
state.splice(index, 1);
|
|
3324
|
+
arraySet.delete(i);
|
|
3304
3325
|
}
|
|
3305
3326
|
});
|
|
3306
3327
|
}
|
|
@@ -3720,17 +3741,34 @@ class Store extends EmberObject {
|
|
|
3720
3741
|
_run(cb) {
|
|
3721
3742
|
assert(`EmberData should never encounter a nested run`, !this._cbs);
|
|
3722
3743
|
const _cbs = this._cbs = {};
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3744
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
3745
|
+
try {
|
|
3746
|
+
cb();
|
|
3747
|
+
if (_cbs.coalesce) {
|
|
3748
|
+
_cbs.coalesce();
|
|
3749
|
+
}
|
|
3750
|
+
if (_cbs.sync) {
|
|
3751
|
+
_cbs.sync();
|
|
3752
|
+
}
|
|
3753
|
+
if (_cbs.notify) {
|
|
3754
|
+
_cbs.notify();
|
|
3755
|
+
}
|
|
3756
|
+
} finally {
|
|
3757
|
+
this._cbs = null;
|
|
3758
|
+
}
|
|
3759
|
+
} else {
|
|
3760
|
+
cb();
|
|
3761
|
+
if (_cbs.coalesce) {
|
|
3762
|
+
_cbs.coalesce();
|
|
3763
|
+
}
|
|
3764
|
+
if (_cbs.sync) {
|
|
3765
|
+
_cbs.sync();
|
|
3766
|
+
}
|
|
3767
|
+
if (_cbs.notify) {
|
|
3768
|
+
_cbs.notify();
|
|
3769
|
+
}
|
|
3770
|
+
this._cbs = null;
|
|
3732
3771
|
}
|
|
3733
|
-
this._cbs = null;
|
|
3734
3772
|
}
|
|
3735
3773
|
_join(cb) {
|
|
3736
3774
|
if (this._cbs) {
|
|
@@ -5017,12 +5055,11 @@ class Store extends EmberObject {
|
|
|
5017
5055
|
// during unload
|
|
5018
5056
|
if (macroCondition(getOwnConfig().packages.HAS_GRAPH_PACKAGE)) {
|
|
5019
5057
|
const peekGraph = importSync('@ember-data/graph/-private').peekGraph;
|
|
5020
|
-
|
|
5058
|
+
const graph = peekGraph(this);
|
|
5021
5059
|
if (graph) {
|
|
5022
5060
|
graph.identifiers.clear();
|
|
5023
5061
|
}
|
|
5024
5062
|
}
|
|
5025
|
-
this.notifications.destroy();
|
|
5026
5063
|
this.recordArrayManager.clear();
|
|
5027
5064
|
this._instanceCache.clear();
|
|
5028
5065
|
} else {
|
|
@@ -5538,6 +5575,7 @@ class Store extends EmberObject {
|
|
|
5538
5575
|
graph.destroy();
|
|
5539
5576
|
}
|
|
5540
5577
|
}
|
|
5578
|
+
this.notifications.destroy();
|
|
5541
5579
|
this.recordArrayManager.destroy();
|
|
5542
5580
|
this.identifierCache.destroy();
|
|
5543
5581
|
this.unloadAll();
|