@ember-data/store 5.4.0-alpha.138 → 5.4.0-alpha.139
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/dist/-private.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{handler-BWl65Bke.js → many-array-DJ3xLLia.js} +536 -21
- package/dist/many-array-DJ3xLLia.js.map +1 -0
- package/package.json +11 -11
- package/unstable-preview-types/-private/managers/cache-manager.d.ts +22 -0
- package/unstable-preview-types/-private/managers/cache-manager.d.ts.map +1 -1
- package/unstable-preview-types/-private/managers/notification-manager.d.ts.map +1 -1
- package/unstable-preview-types/-private/managers/record-array-manager.d.ts +2 -0
- package/unstable-preview-types/-private/managers/record-array-manager.d.ts.map +1 -1
- package/unstable-preview-types/-private/record-arrays/identifier-array.d.ts +11 -1
- package/unstable-preview-types/-private/record-arrays/identifier-array.d.ts.map +1 -1
- package/unstable-preview-types/-private/record-arrays/many-array.d.ts +199 -0
- package/unstable-preview-types/-private/record-arrays/many-array.d.ts.map +1 -0
- package/unstable-preview-types/-private/store-service.d.ts +2 -3
- package/unstable-preview-types/-private/store-service.d.ts.map +1 -1
- package/unstable-preview-types/-private.d.ts +1 -0
- package/unstable-preview-types/-private.d.ts.map +1 -1
- package/unstable-preview-types/index.d.ts +1 -0
- package/dist/handler-BWl65Bke.js.map +0 -1
package/dist/-private.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { A as ARRAY_SIGNAL, C as CacheHandler, j as CollectionRecordArray, I as LiveArray, M as MUTATE, R as RecordArrayManager, k as SOURCE, S as Store, q as StoreMap, _ as _clearCaches, u as _deprecatingNormalize, g as coerceId, f as constructResource, h as ensureStringId, l as fastPush, i as isStableIdentifier,
|
|
1
|
+
export { A as ARRAY_SIGNAL, C as CacheHandler, j as CollectionRecordArray, I as LiveArray, M as MUTATE, R as RecordArrayManager, v as RelatedCollection, k as SOURCE, S as Store, q as StoreMap, _ as _clearCaches, u as _deprecatingNormalize, g as coerceId, f as constructResource, h as ensureStringId, l as fastPush, i as isStableIdentifier, w as log, x as logGroup, n as notifyArray, p as peekCache, r as recordIdentifierFor, m as removeRecordDataFor, t as setCacheFor, o as setRecordIdentifier, s as storeFor } from "./many-array-DJ3xLLia.js";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { C as CacheHandler, S as default, r as recordIdentifierFor, c as setIdentifierForgetMethod, a as setIdentifierGenerationMethod, d as setIdentifierResetMethod, b as setIdentifierUpdateMethod, e as setKeyInfoForResource, s as storeFor } from "./
|
|
1
|
+
export { C as CacheHandler, S as default, r as recordIdentifierFor, c as setIdentifierForgetMethod, a as setIdentifierGenerationMethod, d as setIdentifierResetMethod, b as setIdentifierUpdateMethod, e as setKeyInfoForResource, s as storeFor } from "./many-array-DJ3xLLia.js";
|
|
2
2
|
import '@ember/debug';
|
|
3
3
|
import '@embroider/macros';
|
|
4
4
|
import '@ember-data/request-utils/string';
|
|
@@ -3,10 +3,10 @@ import { macroCondition, getGlobalConfig, dependencySatisfies, importSync } from
|
|
|
3
3
|
import { setLogging, getRuntimeConfig } from '@warp-drive/build-config/runtime';
|
|
4
4
|
import { EnableHydration, SkipCache } from '@warp-drive/core-types/request';
|
|
5
5
|
import { getOrSetGlobal, setTransient, peekTransient } from '@warp-drive/core-types/-private';
|
|
6
|
+
import { _backburner } from '@ember/runloop';
|
|
7
|
+
import { defineSignal, createSignal, subscribe, createArrayTags, addToTransaction, addTransactionCB } from '@ember-data/tracking/-private';
|
|
6
8
|
import { CACHE_OWNER, DEBUG_STALE_CACHE_OWNER, DEBUG_CLIENT_ORIGINATED, DEBUG_IDENTIFIER_BUCKET } from '@warp-drive/core-types/identifier';
|
|
7
9
|
import { dasherize } from '@ember-data/request-utils/string';
|
|
8
|
-
import { defineSignal, createSignal, subscribe, createArrayTags, addToTransaction, addTransactionCB } from '@ember-data/tracking/-private';
|
|
9
|
-
import { _backburner } from '@ember/runloop';
|
|
10
10
|
import { compat } from '@ember-data/tracking';
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -1847,7 +1847,9 @@ class CacheManager {
|
|
|
1847
1847
|
peek(identifier) {
|
|
1848
1848
|
return this.#cache.peek(identifier);
|
|
1849
1849
|
}
|
|
1850
|
-
|
|
1850
|
+
peekRemoteState(identifier) {
|
|
1851
|
+
return this.#cache.peekRemoteState(identifier);
|
|
1852
|
+
}
|
|
1851
1853
|
/**
|
|
1852
1854
|
* Peek the Cache for the existing request data associated with
|
|
1853
1855
|
* a cacheable request
|
|
@@ -2070,6 +2072,19 @@ class CacheManager {
|
|
|
2070
2072
|
return this.#cache.getAttr(identifier, propertyName);
|
|
2071
2073
|
}
|
|
2072
2074
|
|
|
2075
|
+
/**
|
|
2076
|
+
* Retrieve the remote state for an attribute from the cache
|
|
2077
|
+
*
|
|
2078
|
+
* @method getRemoteAttr
|
|
2079
|
+
* @public
|
|
2080
|
+
* @param identifier
|
|
2081
|
+
* @param propertyName
|
|
2082
|
+
* @return {unknown}
|
|
2083
|
+
*/
|
|
2084
|
+
getRemoteAttr(identifier, propertyName) {
|
|
2085
|
+
return this.#cache.getRemoteAttr(identifier, propertyName);
|
|
2086
|
+
}
|
|
2087
|
+
|
|
2073
2088
|
/**
|
|
2074
2089
|
* Mutate the data for an attribute in the cache
|
|
2075
2090
|
*
|
|
@@ -2194,6 +2209,19 @@ class CacheManager {
|
|
|
2194
2209
|
return this.#cache.getRelationship(identifier, propertyName);
|
|
2195
2210
|
}
|
|
2196
2211
|
|
|
2212
|
+
/**
|
|
2213
|
+
* Query the cache for the remote state of a relationship property
|
|
2214
|
+
*
|
|
2215
|
+
* @method getRelationship
|
|
2216
|
+
* @public
|
|
2217
|
+
* @param identifier
|
|
2218
|
+
* @param propertyName
|
|
2219
|
+
* @return resource relationship object
|
|
2220
|
+
*/
|
|
2221
|
+
getRemoteRelationship(identifier, propertyName) {
|
|
2222
|
+
return this.#cache.getRemoteRelationship(identifier, propertyName);
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2197
2225
|
// Resource State
|
|
2198
2226
|
// ===============
|
|
2199
2227
|
|
|
@@ -2290,10 +2318,7 @@ function runLoopIsFlushing() {
|
|
|
2290
2318
|
function count(label) {
|
|
2291
2319
|
// @ts-expect-error
|
|
2292
2320
|
// eslint-disable-next-line
|
|
2293
|
-
globalThis.
|
|
2294
|
-
// @ts-expect-error
|
|
2295
|
-
// eslint-disable-next-line
|
|
2296
|
-
globalThis.counts[label] = (globalThis.counts[label] || 0) + 1;
|
|
2321
|
+
globalThis.__WarpDriveMetricCountData[label] = (globalThis.__WarpDriveMetricCountData[label] || 0) + 1;
|
|
2297
2322
|
}
|
|
2298
2323
|
function _unsubscribe(tokens, token, cache) {
|
|
2299
2324
|
const identifier = tokens.get(token);
|
|
@@ -2827,7 +2852,7 @@ class IdentifierArray {
|
|
|
2827
2852
|
return false;
|
|
2828
2853
|
}
|
|
2829
2854
|
const original = target[index];
|
|
2830
|
-
const newIdentifier = extractIdentifierFromRecord$
|
|
2855
|
+
const newIdentifier = extractIdentifierFromRecord$2(value);
|
|
2831
2856
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2832
2857
|
if (!test) {
|
|
2833
2858
|
throw new Error(`Expected a record`);
|
|
@@ -2868,7 +2893,7 @@ class IdentifierArray {
|
|
|
2868
2893
|
return Reflect.deleteProperty(target, prop);
|
|
2869
2894
|
},
|
|
2870
2895
|
getPrototypeOf() {
|
|
2871
|
-
return
|
|
2896
|
+
return Array.prototype;
|
|
2872
2897
|
}
|
|
2873
2898
|
});
|
|
2874
2899
|
createArrayTags(proxy, _SIGNAL);
|
|
@@ -3011,7 +3036,7 @@ Collection.prototype.query = null;
|
|
|
3011
3036
|
// Ensure instanceof works correctly
|
|
3012
3037
|
// Object.setPrototypeOf(IdentifierArray.prototype, Array.prototype);
|
|
3013
3038
|
|
|
3014
|
-
function assertRecordPassedToHasMany(record) {
|
|
3039
|
+
function assertRecordPassedToHasMany$1(record) {
|
|
3015
3040
|
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
3016
3041
|
if (!test) {
|
|
3017
3042
|
throw new Error(`All elements of a hasMany relationship must be instances of Model, you passed $${typeof record}`);
|
|
@@ -3025,11 +3050,11 @@ function assertRecordPassedToHasMany(record) {
|
|
|
3025
3050
|
}
|
|
3026
3051
|
}()) : {};
|
|
3027
3052
|
}
|
|
3028
|
-
function extractIdentifierFromRecord$
|
|
3053
|
+
function extractIdentifierFromRecord$2(record) {
|
|
3029
3054
|
if (!record) {
|
|
3030
3055
|
return null;
|
|
3031
3056
|
}
|
|
3032
|
-
assertRecordPassedToHasMany(record);
|
|
3057
|
+
assertRecordPassedToHasMany$1(record);
|
|
3033
3058
|
return recordIdentifierFor(record);
|
|
3034
3059
|
}
|
|
3035
3060
|
|
|
@@ -3124,6 +3149,9 @@ class RecordArrayManager {
|
|
|
3124
3149
|
sync(array, pending, this._set.get(array));
|
|
3125
3150
|
this._pending.delete(array);
|
|
3126
3151
|
}
|
|
3152
|
+
mutate(mutation) {
|
|
3153
|
+
this.store.cache.mutate(mutation);
|
|
3154
|
+
}
|
|
3127
3155
|
|
|
3128
3156
|
/**
|
|
3129
3157
|
Get the `RecordArray` for a modelName, which contains all loaded records of
|
|
@@ -3645,6 +3673,23 @@ globalThis.setWarpDriveLogging = setLogging;
|
|
|
3645
3673
|
|
|
3646
3674
|
// @ts-expect-error adding to globalThis
|
|
3647
3675
|
globalThis.getWarpDriveRuntimeConfig = getRuntimeConfig;
|
|
3676
|
+
if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
|
|
3677
|
+
if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
|
|
3678
|
+
// @ts-expect-error
|
|
3679
|
+
// eslint-disable-next-line
|
|
3680
|
+
globalThis.__WarpDriveMetricCountData = globalThis.__WarpDriveMetricCountData || {};
|
|
3681
|
+
// @ts-expect-error
|
|
3682
|
+
// eslint-disable-next-line
|
|
3683
|
+
globalThis.counts[label] = (globalThis.counts[label] || 0) + 1;
|
|
3684
|
+
|
|
3685
|
+
// @ts-expect-error
|
|
3686
|
+
globalThis.getWarpDriveMetricCounts = () => {
|
|
3687
|
+
// @ts-expect-error
|
|
3688
|
+
// eslint-disable-next-line
|
|
3689
|
+
return globalThis.__WarpDriveMetricCountData;
|
|
3690
|
+
};
|
|
3691
|
+
}
|
|
3692
|
+
}
|
|
3648
3693
|
|
|
3649
3694
|
// `AwaitedKeys` is needed here to resolve any promise types like `PromiseBelongsTo`.
|
|
3650
3695
|
|
|
@@ -4253,9 +4298,8 @@ class Store extends BaseClass {
|
|
|
4253
4298
|
This will cause the record to be destroyed and freed up for garbage collection.
|
|
4254
4299
|
Example
|
|
4255
4300
|
```javascript
|
|
4256
|
-
store.findRecord('post', '1')
|
|
4257
|
-
|
|
4258
|
-
});
|
|
4301
|
+
const { content: { data: post } } = await store.request(findRecord({ type: 'post', id: '1' }));
|
|
4302
|
+
store.unloadRecord(post);
|
|
4259
4303
|
```
|
|
4260
4304
|
@method unloadRecord
|
|
4261
4305
|
@public
|
|
@@ -5539,9 +5583,9 @@ function normalizeProperties(store, identifier, properties) {
|
|
|
5539
5583
|
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
5540
5584
|
assertRecordsPassedToHasMany(properties[prop]);
|
|
5541
5585
|
}
|
|
5542
|
-
properties[prop] = extractIdentifiersFromRecords(properties[prop]);
|
|
5586
|
+
properties[prop] = extractIdentifiersFromRecords$1(properties[prop]);
|
|
5543
5587
|
} else if (field.kind === 'belongsTo') {
|
|
5544
|
-
properties[prop] = extractIdentifierFromRecord(properties[prop]);
|
|
5588
|
+
properties[prop] = extractIdentifierFromRecord$1(properties[prop]);
|
|
5545
5589
|
}
|
|
5546
5590
|
}
|
|
5547
5591
|
}
|
|
@@ -5569,10 +5613,10 @@ function assertRecordsPassedToHasMany(records) {
|
|
|
5569
5613
|
});
|
|
5570
5614
|
}()) : {};
|
|
5571
5615
|
}
|
|
5572
|
-
function extractIdentifiersFromRecords(records) {
|
|
5573
|
-
return records.map(record => extractIdentifierFromRecord(record));
|
|
5616
|
+
function extractIdentifiersFromRecords$1(records) {
|
|
5617
|
+
return records.map(record => extractIdentifierFromRecord$1(record));
|
|
5574
5618
|
}
|
|
5575
|
-
function extractIdentifierFromRecord(recordOrPromiseRecord) {
|
|
5619
|
+
function extractIdentifierFromRecord$1(recordOrPromiseRecord) {
|
|
5576
5620
|
if (!recordOrPromiseRecord) {
|
|
5577
5621
|
return null;
|
|
5578
5622
|
}
|
|
@@ -6220,4 +6264,475 @@ function fetchContentAndHydrate(next, context, identifier, priority) {
|
|
|
6220
6264
|
}]
|
|
6221
6265
|
});
|
|
6222
6266
|
}
|
|
6223
|
-
|
|
6267
|
+
|
|
6268
|
+
/**
|
|
6269
|
+
@module @ember-data/store
|
|
6270
|
+
*/
|
|
6271
|
+
/**
|
|
6272
|
+
A `ManyArray` is a `MutableArray` that represents the contents of a has-many
|
|
6273
|
+
relationship.
|
|
6274
|
+
|
|
6275
|
+
The `ManyArray` is instantiated lazily the first time the relationship is
|
|
6276
|
+
requested.
|
|
6277
|
+
|
|
6278
|
+
This class is not intended to be directly instantiated by consuming applications.
|
|
6279
|
+
|
|
6280
|
+
### Inverses
|
|
6281
|
+
|
|
6282
|
+
Often, the relationships in Ember Data applications will have
|
|
6283
|
+
an inverse. For example, imagine the following models are
|
|
6284
|
+
defined:
|
|
6285
|
+
|
|
6286
|
+
```app/models/post.js
|
|
6287
|
+
import Model, { hasMany } from '@ember-data/model';
|
|
6288
|
+
|
|
6289
|
+
export default class PostModel extends Model {
|
|
6290
|
+
@hasMany('comment') comments;
|
|
6291
|
+
}
|
|
6292
|
+
```
|
|
6293
|
+
|
|
6294
|
+
```app/models/comment.js
|
|
6295
|
+
import Model, { belongsTo } from '@ember-data/model';
|
|
6296
|
+
|
|
6297
|
+
export default class CommentModel extends Model {
|
|
6298
|
+
@belongsTo('post') post;
|
|
6299
|
+
}
|
|
6300
|
+
```
|
|
6301
|
+
|
|
6302
|
+
If you created a new instance of `Post` and added
|
|
6303
|
+
a `Comment` record to its `comments` has-many
|
|
6304
|
+
relationship, you would expect the comment's `post`
|
|
6305
|
+
property to be set to the post that contained
|
|
6306
|
+
the has-many.
|
|
6307
|
+
|
|
6308
|
+
We call the record to which a relationship belongs-to the
|
|
6309
|
+
relationship's _owner_.
|
|
6310
|
+
|
|
6311
|
+
@class ManyArray
|
|
6312
|
+
@public
|
|
6313
|
+
*/
|
|
6314
|
+
class RelatedCollection extends IdentifierArray {
|
|
6315
|
+
/**
|
|
6316
|
+
The loading state of this array
|
|
6317
|
+
@property {Boolean} isLoaded
|
|
6318
|
+
@public
|
|
6319
|
+
*/
|
|
6320
|
+
|
|
6321
|
+
/**
|
|
6322
|
+
`true` if the relationship is polymorphic, `false` otherwise.
|
|
6323
|
+
@property {Boolean} isPolymorphic
|
|
6324
|
+
@private
|
|
6325
|
+
*/
|
|
6326
|
+
|
|
6327
|
+
/**
|
|
6328
|
+
Metadata associated with the request for async hasMany relationships.
|
|
6329
|
+
Example
|
|
6330
|
+
Given that the server returns the following JSON payload when fetching a
|
|
6331
|
+
hasMany relationship:
|
|
6332
|
+
```js
|
|
6333
|
+
{
|
|
6334
|
+
"comments": [{
|
|
6335
|
+
"id": 1,
|
|
6336
|
+
"comment": "This is the first comment",
|
|
6337
|
+
}, {
|
|
6338
|
+
// ...
|
|
6339
|
+
}],
|
|
6340
|
+
"meta": {
|
|
6341
|
+
"page": 1,
|
|
6342
|
+
"total": 5
|
|
6343
|
+
}
|
|
6344
|
+
}
|
|
6345
|
+
```
|
|
6346
|
+
You can then access the meta data via the `meta` property:
|
|
6347
|
+
```js
|
|
6348
|
+
let comments = await post.comments;
|
|
6349
|
+
let meta = comments.meta;
|
|
6350
|
+
// meta.page => 1
|
|
6351
|
+
// meta.total => 5
|
|
6352
|
+
```
|
|
6353
|
+
@property {Object | null} meta
|
|
6354
|
+
@public
|
|
6355
|
+
*/
|
|
6356
|
+
|
|
6357
|
+
/**
|
|
6358
|
+
* Retrieve the links for this relationship
|
|
6359
|
+
*
|
|
6360
|
+
@property {Object | null} links
|
|
6361
|
+
@public
|
|
6362
|
+
*/
|
|
6363
|
+
|
|
6364
|
+
constructor(options) {
|
|
6365
|
+
super(options);
|
|
6366
|
+
this.isLoaded = options.isLoaded || false;
|
|
6367
|
+
this.isAsync = options.isAsync || false;
|
|
6368
|
+
this.isPolymorphic = options.isPolymorphic || false;
|
|
6369
|
+
this.identifier = options.identifier;
|
|
6370
|
+
this.key = options.key;
|
|
6371
|
+
}
|
|
6372
|
+
[MUTATE](target, receiver, prop, args, _SIGNAL) {
|
|
6373
|
+
switch (prop) {
|
|
6374
|
+
case 'length 0':
|
|
6375
|
+
{
|
|
6376
|
+
Reflect.set(target, 'length', 0);
|
|
6377
|
+
mutateReplaceRelatedRecords(this, [], _SIGNAL);
|
|
6378
|
+
return true;
|
|
6379
|
+
}
|
|
6380
|
+
case 'replace cell':
|
|
6381
|
+
{
|
|
6382
|
+
const [index, prior, value] = args;
|
|
6383
|
+
target[index] = value;
|
|
6384
|
+
mutateReplaceRelatedRecord(this, {
|
|
6385
|
+
value,
|
|
6386
|
+
prior,
|
|
6387
|
+
index
|
|
6388
|
+
}, _SIGNAL);
|
|
6389
|
+
return true;
|
|
6390
|
+
}
|
|
6391
|
+
case 'push':
|
|
6392
|
+
{
|
|
6393
|
+
const newValues = extractIdentifiersFromRecords(args);
|
|
6394
|
+
assertNoDuplicates(this, target, currentState => currentState.push(...newValues), `Cannot push duplicates to a hasMany's state.`);
|
|
6395
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
6396
|
+
// dedupe
|
|
6397
|
+
const seen = new Set(target);
|
|
6398
|
+
const unique = new Set();
|
|
6399
|
+
args.forEach(item => {
|
|
6400
|
+
const identifier = recordIdentifierFor(item);
|
|
6401
|
+
if (!seen.has(identifier)) {
|
|
6402
|
+
seen.add(identifier);
|
|
6403
|
+
unique.add(item);
|
|
6404
|
+
}
|
|
6405
|
+
});
|
|
6406
|
+
const newArgs = Array.from(unique);
|
|
6407
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
6408
|
+
if (newArgs.length) {
|
|
6409
|
+
mutateAddToRelatedRecords(this, {
|
|
6410
|
+
value: extractIdentifiersFromRecords(newArgs)
|
|
6411
|
+
}, _SIGNAL);
|
|
6412
|
+
}
|
|
6413
|
+
return result;
|
|
6414
|
+
}
|
|
6415
|
+
|
|
6416
|
+
// else, no dedupe, error on duplicates
|
|
6417
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6418
|
+
if (newValues.length) {
|
|
6419
|
+
mutateAddToRelatedRecords(this, {
|
|
6420
|
+
value: newValues
|
|
6421
|
+
}, _SIGNAL);
|
|
6422
|
+
}
|
|
6423
|
+
return result;
|
|
6424
|
+
}
|
|
6425
|
+
case 'pop':
|
|
6426
|
+
{
|
|
6427
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6428
|
+
if (result) {
|
|
6429
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
6430
|
+
value: recordIdentifierFor(result)
|
|
6431
|
+
}, _SIGNAL);
|
|
6432
|
+
}
|
|
6433
|
+
return result;
|
|
6434
|
+
}
|
|
6435
|
+
case 'unshift':
|
|
6436
|
+
{
|
|
6437
|
+
const newValues = extractIdentifiersFromRecords(args);
|
|
6438
|
+
assertNoDuplicates(this, target, currentState => currentState.unshift(...newValues), `Cannot unshift duplicates to a hasMany's state.`);
|
|
6439
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
6440
|
+
// dedupe
|
|
6441
|
+
const seen = new Set(target);
|
|
6442
|
+
const unique = new Set();
|
|
6443
|
+
args.forEach(item => {
|
|
6444
|
+
const identifier = recordIdentifierFor(item);
|
|
6445
|
+
if (!seen.has(identifier)) {
|
|
6446
|
+
seen.add(identifier);
|
|
6447
|
+
unique.add(item);
|
|
6448
|
+
}
|
|
6449
|
+
});
|
|
6450
|
+
const newArgs = Array.from(unique);
|
|
6451
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
6452
|
+
if (newArgs.length) {
|
|
6453
|
+
mutateAddToRelatedRecords(this, {
|
|
6454
|
+
value: extractIdentifiersFromRecords(newArgs),
|
|
6455
|
+
index: 0
|
|
6456
|
+
}, _SIGNAL);
|
|
6457
|
+
}
|
|
6458
|
+
return result;
|
|
6459
|
+
}
|
|
6460
|
+
|
|
6461
|
+
// else, no dedupe, error on duplicates
|
|
6462
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6463
|
+
if (newValues.length) {
|
|
6464
|
+
mutateAddToRelatedRecords(this, {
|
|
6465
|
+
value: newValues,
|
|
6466
|
+
index: 0
|
|
6467
|
+
}, _SIGNAL);
|
|
6468
|
+
}
|
|
6469
|
+
return result;
|
|
6470
|
+
}
|
|
6471
|
+
case 'shift':
|
|
6472
|
+
{
|
|
6473
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6474
|
+
if (result) {
|
|
6475
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
6476
|
+
value: recordIdentifierFor(result),
|
|
6477
|
+
index: 0
|
|
6478
|
+
}, _SIGNAL);
|
|
6479
|
+
}
|
|
6480
|
+
return result;
|
|
6481
|
+
}
|
|
6482
|
+
case 'sort':
|
|
6483
|
+
{
|
|
6484
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6485
|
+
mutateSortRelatedRecords(this, result.map(recordIdentifierFor), _SIGNAL);
|
|
6486
|
+
return result;
|
|
6487
|
+
}
|
|
6488
|
+
case 'splice':
|
|
6489
|
+
{
|
|
6490
|
+
const [start, deleteCount, ...adds] = args;
|
|
6491
|
+
|
|
6492
|
+
// detect a full replace
|
|
6493
|
+
if (start === 0 && deleteCount === this[SOURCE].length) {
|
|
6494
|
+
const newValues = extractIdentifiersFromRecords(adds);
|
|
6495
|
+
assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot replace a hasMany's state with a new state that contains duplicates.`);
|
|
6496
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
6497
|
+
// dedupe
|
|
6498
|
+
const current = new Set(adds);
|
|
6499
|
+
const unique = Array.from(current);
|
|
6500
|
+
const newArgs = [start, deleteCount].concat(unique);
|
|
6501
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
6502
|
+
mutateReplaceRelatedRecords(this, extractIdentifiersFromRecords(unique), _SIGNAL);
|
|
6503
|
+
return result;
|
|
6504
|
+
}
|
|
6505
|
+
|
|
6506
|
+
// else, no dedupe, error on duplicates
|
|
6507
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6508
|
+
mutateReplaceRelatedRecords(this, newValues, _SIGNAL);
|
|
6509
|
+
return result;
|
|
6510
|
+
}
|
|
6511
|
+
const newValues = extractIdentifiersFromRecords(adds);
|
|
6512
|
+
assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot splice a hasMany's state with a new state that contains duplicates.`);
|
|
6513
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
6514
|
+
// dedupe
|
|
6515
|
+
const currentState = target.slice();
|
|
6516
|
+
currentState.splice(start, deleteCount);
|
|
6517
|
+
const seen = new Set(currentState);
|
|
6518
|
+
const unique = [];
|
|
6519
|
+
adds.forEach(item => {
|
|
6520
|
+
const identifier = recordIdentifierFor(item);
|
|
6521
|
+
if (!seen.has(identifier)) {
|
|
6522
|
+
seen.add(identifier);
|
|
6523
|
+
unique.push(item);
|
|
6524
|
+
}
|
|
6525
|
+
});
|
|
6526
|
+
const newArgs = [start, deleteCount, ...unique];
|
|
6527
|
+
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
6528
|
+
if (deleteCount > 0) {
|
|
6529
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
6530
|
+
value: result.map(recordIdentifierFor),
|
|
6531
|
+
index: start
|
|
6532
|
+
}, _SIGNAL);
|
|
6533
|
+
}
|
|
6534
|
+
if (unique.length > 0) {
|
|
6535
|
+
mutateAddToRelatedRecords(this, {
|
|
6536
|
+
value: extractIdentifiersFromRecords(unique),
|
|
6537
|
+
index: start
|
|
6538
|
+
}, _SIGNAL);
|
|
6539
|
+
}
|
|
6540
|
+
return result;
|
|
6541
|
+
}
|
|
6542
|
+
|
|
6543
|
+
// else, no dedupe, error on duplicates
|
|
6544
|
+
const result = Reflect.apply(target[prop], receiver, args);
|
|
6545
|
+
if (deleteCount > 0) {
|
|
6546
|
+
mutateRemoveFromRelatedRecords(this, {
|
|
6547
|
+
value: result.map(recordIdentifierFor),
|
|
6548
|
+
index: start
|
|
6549
|
+
}, _SIGNAL);
|
|
6550
|
+
}
|
|
6551
|
+
if (newValues.length > 0) {
|
|
6552
|
+
mutateAddToRelatedRecords(this, {
|
|
6553
|
+
value: newValues,
|
|
6554
|
+
index: start
|
|
6555
|
+
}, _SIGNAL);
|
|
6556
|
+
}
|
|
6557
|
+
return result;
|
|
6558
|
+
}
|
|
6559
|
+
default:
|
|
6560
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
6561
|
+
{
|
|
6562
|
+
throw new Error(`unable to convert ${prop} into a transaction that updates the cache state for this record array`);
|
|
6563
|
+
}
|
|
6564
|
+
})() : {};
|
|
6565
|
+
}
|
|
6566
|
+
}
|
|
6567
|
+
notify() {
|
|
6568
|
+
const signal = this[ARRAY_SIGNAL];
|
|
6569
|
+
signal.shouldReset = true;
|
|
6570
|
+
notifyArray(this);
|
|
6571
|
+
}
|
|
6572
|
+
|
|
6573
|
+
/**
|
|
6574
|
+
Reloads all of the records in the manyArray. If the manyArray
|
|
6575
|
+
holds a relationship that was originally fetched using a links url
|
|
6576
|
+
EmberData will revisit the original links url to repopulate the
|
|
6577
|
+
relationship.
|
|
6578
|
+
If the ManyArray holds the result of a `store.query()` reload will
|
|
6579
|
+
re-run the original query.
|
|
6580
|
+
Example
|
|
6581
|
+
```javascript
|
|
6582
|
+
let user = store.peekRecord('user', '1')
|
|
6583
|
+
await login(user);
|
|
6584
|
+
let permissions = await user.permissions;
|
|
6585
|
+
await permissions.reload();
|
|
6586
|
+
```
|
|
6587
|
+
@method reload
|
|
6588
|
+
@public
|
|
6589
|
+
*/
|
|
6590
|
+
reload(options) {
|
|
6591
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
6592
|
+
if (!test) {
|
|
6593
|
+
throw new Error(`Expected the manager for ManyArray to implement reloadHasMany`);
|
|
6594
|
+
}
|
|
6595
|
+
})(typeof this._manager.reloadHasMany === 'function') : {};
|
|
6596
|
+
// TODO this is odd, we don't ask the store for anything else like this?
|
|
6597
|
+
return this._manager.reloadHasMany(this.key, options);
|
|
6598
|
+
}
|
|
6599
|
+
|
|
6600
|
+
/**
|
|
6601
|
+
Saves all of the records in the `ManyArray`.
|
|
6602
|
+
Note: this API can only be used in legacy mode with a configured Adapter.
|
|
6603
|
+
Example
|
|
6604
|
+
```javascript
|
|
6605
|
+
const { content: { data: inbox } } = await store.request(findRecord({ type: 'inbox', id: '1' }));
|
|
6606
|
+
let messages = await inbox.messages;
|
|
6607
|
+
messages.forEach((message) => {
|
|
6608
|
+
message.isRead = true;
|
|
6609
|
+
});
|
|
6610
|
+
messages.save();
|
|
6611
|
+
```
|
|
6612
|
+
@method save
|
|
6613
|
+
@public
|
|
6614
|
+
@return {PromiseArray} promise
|
|
6615
|
+
*/
|
|
6616
|
+
|
|
6617
|
+
/**
|
|
6618
|
+
Create a child record within the owner
|
|
6619
|
+
@method createRecord
|
|
6620
|
+
@public
|
|
6621
|
+
@param {Object} hash
|
|
6622
|
+
@return {Model} record
|
|
6623
|
+
*/
|
|
6624
|
+
createRecord(hash) {
|
|
6625
|
+
const {
|
|
6626
|
+
store
|
|
6627
|
+
} = this;
|
|
6628
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
6629
|
+
if (!test) {
|
|
6630
|
+
throw new Error(`Expected modelName to be set`);
|
|
6631
|
+
}
|
|
6632
|
+
})(this.modelName) : {};
|
|
6633
|
+
const record = store.createRecord(this.modelName, hash);
|
|
6634
|
+
this.push(record);
|
|
6635
|
+
return record;
|
|
6636
|
+
}
|
|
6637
|
+
destroy() {
|
|
6638
|
+
super.destroy(false);
|
|
6639
|
+
}
|
|
6640
|
+
}
|
|
6641
|
+
RelatedCollection.prototype.isAsync = false;
|
|
6642
|
+
RelatedCollection.prototype.isPolymorphic = false;
|
|
6643
|
+
RelatedCollection.prototype.identifier = null;
|
|
6644
|
+
RelatedCollection.prototype.cache = null;
|
|
6645
|
+
RelatedCollection.prototype._inverseIsAsync = false;
|
|
6646
|
+
RelatedCollection.prototype.key = '';
|
|
6647
|
+
RelatedCollection.prototype.DEPRECATED_CLASS_NAME = 'ManyArray';
|
|
6648
|
+
function assertRecordPassedToHasMany(record) {
|
|
6649
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
6650
|
+
if (!test) {
|
|
6651
|
+
throw new Error(`All elements of a hasMany relationship must be instances of Model, you passed ${typeof record}`);
|
|
6652
|
+
}
|
|
6653
|
+
})(function () {
|
|
6654
|
+
try {
|
|
6655
|
+
recordIdentifierFor(record);
|
|
6656
|
+
return true;
|
|
6657
|
+
} catch {
|
|
6658
|
+
return false;
|
|
6659
|
+
}
|
|
6660
|
+
}()) : {};
|
|
6661
|
+
}
|
|
6662
|
+
function extractIdentifiersFromRecords(records) {
|
|
6663
|
+
return records.map(extractIdentifierFromRecord);
|
|
6664
|
+
}
|
|
6665
|
+
function extractIdentifierFromRecord(recordOrPromiseRecord) {
|
|
6666
|
+
assertRecordPassedToHasMany(recordOrPromiseRecord);
|
|
6667
|
+
return recordIdentifierFor(recordOrPromiseRecord);
|
|
6668
|
+
}
|
|
6669
|
+
function assertNoDuplicates(collection, target, callback, reason) {
|
|
6670
|
+
const state = target.slice();
|
|
6671
|
+
callback(state);
|
|
6672
|
+
if (state.length !== new Set(state).size) {
|
|
6673
|
+
const duplicates = state.filter((currentValue, currentIndex) => state.indexOf(currentValue) !== currentIndex);
|
|
6674
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
6675
|
+
deprecate(`${reason} This behavior is deprecated. Found duplicates for the following records within the new state provided to \`<${collection.identifier.type}:${collection.identifier.id || collection.identifier.lid}>.${collection.key}\`\n\t- ${Array.from(new Set(duplicates)).map(r => isStableIdentifier(r) ? r.lid : recordIdentifierFor(r).lid).sort((a, b) => a.localeCompare(b)).join('\n\t- ')}`, false, {
|
|
6676
|
+
id: 'ember-data:deprecate-many-array-duplicates',
|
|
6677
|
+
for: 'ember-data',
|
|
6678
|
+
until: '6.0',
|
|
6679
|
+
since: {
|
|
6680
|
+
enabled: '5.3',
|
|
6681
|
+
available: '4.13'
|
|
6682
|
+
}
|
|
6683
|
+
});
|
|
6684
|
+
} else {
|
|
6685
|
+
throw new Error(`${reason} Found duplicates for the following records within the new state provided to \`<${collection.identifier.type}:${collection.identifier.id || collection.identifier.lid}>.${collection.key}\`\n\t- ${Array.from(new Set(duplicates)).map(r => isStableIdentifier(r) ? r.lid : recordIdentifierFor(r).lid).sort((a, b) => a.localeCompare(b)).join('\n\t- ')}`);
|
|
6686
|
+
}
|
|
6687
|
+
}
|
|
6688
|
+
}
|
|
6689
|
+
function mutateAddToRelatedRecords(collection, operationInfo, _SIGNAL) {
|
|
6690
|
+
mutate(collection, {
|
|
6691
|
+
op: 'addToRelatedRecords',
|
|
6692
|
+
record: collection.identifier,
|
|
6693
|
+
field: collection.key,
|
|
6694
|
+
...operationInfo
|
|
6695
|
+
}, _SIGNAL);
|
|
6696
|
+
}
|
|
6697
|
+
function mutateRemoveFromRelatedRecords(collection, operationInfo, _SIGNAL) {
|
|
6698
|
+
mutate(collection, {
|
|
6699
|
+
op: 'removeFromRelatedRecords',
|
|
6700
|
+
record: collection.identifier,
|
|
6701
|
+
field: collection.key,
|
|
6702
|
+
...operationInfo
|
|
6703
|
+
}, _SIGNAL);
|
|
6704
|
+
}
|
|
6705
|
+
function mutateReplaceRelatedRecord(collection, operationInfo, _SIGNAL) {
|
|
6706
|
+
mutate(collection, {
|
|
6707
|
+
op: 'replaceRelatedRecord',
|
|
6708
|
+
record: collection.identifier,
|
|
6709
|
+
field: collection.key,
|
|
6710
|
+
...operationInfo
|
|
6711
|
+
}, _SIGNAL);
|
|
6712
|
+
}
|
|
6713
|
+
function mutateReplaceRelatedRecords(collection, value, _SIGNAL) {
|
|
6714
|
+
mutate(collection, {
|
|
6715
|
+
op: 'replaceRelatedRecords',
|
|
6716
|
+
record: collection.identifier,
|
|
6717
|
+
field: collection.key,
|
|
6718
|
+
value
|
|
6719
|
+
}, _SIGNAL);
|
|
6720
|
+
}
|
|
6721
|
+
function mutateSortRelatedRecords(collection, value, _SIGNAL) {
|
|
6722
|
+
mutate(collection, {
|
|
6723
|
+
op: 'sortRelatedRecords',
|
|
6724
|
+
record: collection.identifier,
|
|
6725
|
+
field: collection.key,
|
|
6726
|
+
value
|
|
6727
|
+
}, _SIGNAL);
|
|
6728
|
+
}
|
|
6729
|
+
function mutate(collection, mutation, _SIGNAL) {
|
|
6730
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
6731
|
+
if (!test) {
|
|
6732
|
+
throw new Error(`Expected the manager for ManyArray to implement mutate`);
|
|
6733
|
+
}
|
|
6734
|
+
})(typeof collection._manager.mutate === 'function') : {};
|
|
6735
|
+
collection._manager.mutate(mutation);
|
|
6736
|
+
addToTransaction(_SIGNAL);
|
|
6737
|
+
}
|
|
6738
|
+
export { ARRAY_SIGNAL as A, CacheHandler as C, IdentifierArray as I, MUTATE as M, RecordArrayManager as R, Store as S, _clearCaches as _, setIdentifierGenerationMethod as a, setIdentifierUpdateMethod as b, setIdentifierForgetMethod as c, setIdentifierResetMethod as d, setKeyInfoForResource as e, constructResource as f, coerceId as g, ensureStringId as h, isStableIdentifier as i, Collection as j, SOURCE as k, fastPush as l, removeRecordDataFor as m, notifyArray as n, setRecordIdentifier as o, peekCache as p, StoreMap as q, recordIdentifierFor as r, storeFor as s, setCacheFor as t, normalizeModelName as u, RelatedCollection as v, log as w, logGroup as x };
|