@ember-data/model 5.3.11 → 5.3.13

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.
Files changed (60) hide show
  1. package/LICENSE.md +19 -7
  2. package/README.md +2 -2
  3. package/dist/-private.js +3 -2
  4. package/dist/-private.js.map +1 -1
  5. package/dist/{has-many-BlJm_gf3.js → has-many-DT3JBYYG.js} +1 -1
  6. package/dist/{has-many-BlJm_gf3.js.map → has-many-DT3JBYYG.js.map} +1 -1
  7. package/dist/{hooks-CkH3DloZ.js → hooks-CNY5g4Ab.js} +2 -2
  8. package/dist/{hooks-CkH3DloZ.js.map → hooks-CNY5g4Ab.js.map} +1 -1
  9. package/dist/hooks.js +2 -2
  10. package/dist/index.js +5 -4
  11. package/dist/index.js.map +1 -1
  12. package/dist/migration-support.js +5 -2
  13. package/dist/migration-support.js.map +1 -1
  14. package/dist/{model-CGNpakSA.js → model-rk3atPqV.js} +90 -566
  15. package/dist/model-rk3atPqV.js.map +1 -0
  16. package/dist/{schema-provider-CAdwIBw4.js → schema-provider-Bvogtzx9.js} +4 -1
  17. package/dist/schema-provider-Bvogtzx9.js.map +1 -0
  18. package/logos/NCC-1701-a-blue.svg +4 -0
  19. package/logos/NCC-1701-a-gold.svg +4 -0
  20. package/logos/NCC-1701-a-gold_100.svg +1 -0
  21. package/logos/NCC-1701-a-gold_base-64.txt +1 -0
  22. package/logos/NCC-1701-a.svg +4 -0
  23. package/logos/README.md +4 -0
  24. package/logos/docs-badge.svg +2 -0
  25. package/logos/github-header.svg +444 -0
  26. package/logos/social1.png +0 -0
  27. package/logos/social2.png +0 -0
  28. package/logos/warp-drive-logo-dark.svg +4 -0
  29. package/logos/warp-drive-logo-gold.svg +4 -0
  30. package/package.json +35 -66
  31. package/unstable-preview-types/-private/debug/assert-polymorphic-type.d.ts.map +1 -1
  32. package/unstable-preview-types/-private/legacy-relationships-support.d.ts +1 -1
  33. package/unstable-preview-types/-private/legacy-relationships-support.d.ts.map +1 -1
  34. package/unstable-preview-types/-private/model.d.ts +21 -23
  35. package/unstable-preview-types/-private/model.d.ts.map +1 -1
  36. package/unstable-preview-types/-private/notify-changes.d.ts.map +1 -1
  37. package/unstable-preview-types/-private/promise-many-array.d.ts +1 -1
  38. package/unstable-preview-types/-private/promise-many-array.d.ts.map +1 -1
  39. package/unstable-preview-types/-private/promise-proxy-base.d.ts +5 -0
  40. package/unstable-preview-types/-private/promise-proxy-base.d.ts.map +1 -0
  41. package/unstable-preview-types/-private/record-state.d.ts +1 -11
  42. package/unstable-preview-types/-private/record-state.d.ts.map +1 -1
  43. package/unstable-preview-types/-private/references/has-many.d.ts +1 -1
  44. package/unstable-preview-types/-private/references/has-many.d.ts.map +1 -1
  45. package/unstable-preview-types/-private/schema-provider.d.ts +8 -7
  46. package/unstable-preview-types/-private/schema-provider.d.ts.map +1 -1
  47. package/unstable-preview-types/-private/type-utils.d.ts +1 -1
  48. package/unstable-preview-types/-private/type-utils.d.ts.map +1 -1
  49. package/unstable-preview-types/-private.d.ts +1 -1
  50. package/unstable-preview-types/-private.d.ts.map +1 -1
  51. package/unstable-preview-types/index.d.ts +19 -19
  52. package/unstable-preview-types/index.d.ts.map +1 -1
  53. package/unstable-preview-types/migration-support.d.ts +5 -4
  54. package/unstable-preview-types/migration-support.d.ts.map +1 -1
  55. package/dist/model-CGNpakSA.js.map +0 -1
  56. package/dist/schema-provider-CAdwIBw4.js.map +0 -1
  57. package/unstable-preview-types/-private/many-array.d.ts +0 -196
  58. package/unstable-preview-types/-private/many-array.d.ts.map +0 -1
  59. /package/{ember-data-logo-dark.svg → logos/ember-data-logo-dark.svg} +0 -0
  60. /package/{ember-data-logo-light.svg → logos/ember-data-logo-light.svg} +0 -0
@@ -3,9 +3,9 @@ import { dasherize } from '@ember-data/request-utils/string';
3
3
  import { macroCondition, getGlobalConfig, dependencySatisfies, importSync } from '@embroider/macros';
4
4
  import EmberObject, { computed, get } from '@ember/object';
5
5
  import { recordIdentifierFor as recordIdentifierFor$1, storeFor as storeFor$1 } from '@ember-data/store';
6
- import { LiveArray, MUTATE, SOURCE, recordIdentifierFor, ARRAY_SIGNAL, notifyArray, isStableIdentifier, storeFor, peekCache, fastPush, coerceId } from '@ember-data/store/-private';
7
- import { cached, compat } from '@ember-data/tracking';
8
- import { addToTransaction, defineSignal, peekSignal, getSignal, subscribe } from '@ember-data/tracking/-private';
6
+ import { isStableIdentifier, recordIdentifierFor, storeFor, peekCache, SOURCE, fastPush, RelatedCollection, coerceId } from '@ember-data/store/-private';
7
+ import { cached, compat, notifySignal } from '@ember-data/tracking';
8
+ import { defineSignal, subscribed } from '@ember-data/tracking/-private';
9
9
  import { RecordStore } from '@warp-drive/core-types/symbols';
10
10
  import { A } from '@ember/array';
11
11
  import ArrayProxy from '@ember/array/proxy';
@@ -47,466 +47,6 @@ function normalizeModelName(type) {
47
47
  }
48
48
  return type;
49
49
  }
50
-
51
- /**
52
- @module @ember-data/store
53
- */
54
- /**
55
- A `ManyArray` is a `MutableArray` that represents the contents of a has-many
56
- relationship.
57
-
58
- The `ManyArray` is instantiated lazily the first time the relationship is
59
- requested.
60
-
61
- This class is not intended to be directly instantiated by consuming applications.
62
-
63
- ### Inverses
64
-
65
- Often, the relationships in Ember Data applications will have
66
- an inverse. For example, imagine the following models are
67
- defined:
68
-
69
- ```app/models/post.js
70
- import Model, { hasMany } from '@ember-data/model';
71
-
72
- export default class PostModel extends Model {
73
- @hasMany('comment') comments;
74
- }
75
- ```
76
-
77
- ```app/models/comment.js
78
- import Model, { belongsTo } from '@ember-data/model';
79
-
80
- export default class CommentModel extends Model {
81
- @belongsTo('post') post;
82
- }
83
- ```
84
-
85
- If you created a new instance of `Post` and added
86
- a `Comment` record to its `comments` has-many
87
- relationship, you would expect the comment's `post`
88
- property to be set to the post that contained
89
- the has-many.
90
-
91
- We call the record to which a relationship belongs-to the
92
- relationship's _owner_.
93
-
94
- @class ManyArray
95
- @public
96
- */
97
- class RelatedCollection extends LiveArray {
98
- /**
99
- The loading state of this array
100
- @property {Boolean} isLoaded
101
- @public
102
- */
103
-
104
- /**
105
- `true` if the relationship is polymorphic, `false` otherwise.
106
- @property {Boolean} isPolymorphic
107
- @private
108
- */
109
-
110
- /**
111
- Metadata associated with the request for async hasMany relationships.
112
- Example
113
- Given that the server returns the following JSON payload when fetching a
114
- hasMany relationship:
115
- ```js
116
- {
117
- "comments": [{
118
- "id": 1,
119
- "comment": "This is the first comment",
120
- }, {
121
- // ...
122
- }],
123
- "meta": {
124
- "page": 1,
125
- "total": 5
126
- }
127
- }
128
- ```
129
- You can then access the meta data via the `meta` property:
130
- ```js
131
- let comments = await post.comments;
132
- let meta = comments.meta;
133
- // meta.page => 1
134
- // meta.total => 5
135
- ```
136
- @property {Object | null} meta
137
- @public
138
- */
139
-
140
- /**
141
- * Retrieve the links for this relationship
142
- *
143
- @property {Object | null} links
144
- @public
145
- */
146
-
147
- constructor(options) {
148
- super(options);
149
- this.isLoaded = options.isLoaded || false;
150
- this.isAsync = options.isAsync || false;
151
- this.isPolymorphic = options.isPolymorphic || false;
152
- this.identifier = options.identifier;
153
- this.key = options.key;
154
- }
155
- [MUTATE](target, receiver, prop, args, _SIGNAL) {
156
- switch (prop) {
157
- case 'length 0':
158
- {
159
- Reflect.set(target, 'length', 0);
160
- mutateReplaceRelatedRecords(this, [], _SIGNAL);
161
- return true;
162
- }
163
- case 'replace cell':
164
- {
165
- const [index, prior, value] = args;
166
- target[index] = value;
167
- mutateReplaceRelatedRecord(this, {
168
- value,
169
- prior,
170
- index
171
- }, _SIGNAL);
172
- return true;
173
- }
174
- case 'push':
175
- {
176
- const newValues = extractIdentifiersFromRecords(args);
177
- assertNoDuplicates(this, target, currentState => currentState.push(...newValues), `Cannot push duplicates to a hasMany's state.`);
178
- if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
179
- // dedupe
180
- const seen = new Set(target);
181
- const unique = new Set();
182
- args.forEach(item => {
183
- const identifier = recordIdentifierFor(item);
184
- if (!seen.has(identifier)) {
185
- seen.add(identifier);
186
- unique.add(item);
187
- }
188
- });
189
- const newArgs = Array.from(unique);
190
- const result = Reflect.apply(target[prop], receiver, newArgs);
191
- if (newArgs.length) {
192
- mutateAddToRelatedRecords(this, {
193
- value: extractIdentifiersFromRecords(newArgs)
194
- }, _SIGNAL);
195
- }
196
- return result;
197
- }
198
-
199
- // else, no dedupe, error on duplicates
200
- const result = Reflect.apply(target[prop], receiver, args);
201
- if (newValues.length) {
202
- mutateAddToRelatedRecords(this, {
203
- value: newValues
204
- }, _SIGNAL);
205
- }
206
- return result;
207
- }
208
- case 'pop':
209
- {
210
- const result = Reflect.apply(target[prop], receiver, args);
211
- if (result) {
212
- mutateRemoveFromRelatedRecords(this, {
213
- value: recordIdentifierFor(result)
214
- }, _SIGNAL);
215
- }
216
- return result;
217
- }
218
- case 'unshift':
219
- {
220
- const newValues = extractIdentifiersFromRecords(args);
221
- assertNoDuplicates(this, target, currentState => currentState.unshift(...newValues), `Cannot unshift duplicates to a hasMany's state.`);
222
- if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
223
- // dedupe
224
- const seen = new Set(target);
225
- const unique = new Set();
226
- args.forEach(item => {
227
- const identifier = recordIdentifierFor(item);
228
- if (!seen.has(identifier)) {
229
- seen.add(identifier);
230
- unique.add(item);
231
- }
232
- });
233
- const newArgs = Array.from(unique);
234
- const result = Reflect.apply(target[prop], receiver, newArgs);
235
- if (newArgs.length) {
236
- mutateAddToRelatedRecords(this, {
237
- value: extractIdentifiersFromRecords(newArgs),
238
- index: 0
239
- }, _SIGNAL);
240
- }
241
- return result;
242
- }
243
-
244
- // else, no dedupe, error on duplicates
245
- const result = Reflect.apply(target[prop], receiver, args);
246
- if (newValues.length) {
247
- mutateAddToRelatedRecords(this, {
248
- value: newValues,
249
- index: 0
250
- }, _SIGNAL);
251
- }
252
- return result;
253
- }
254
- case 'shift':
255
- {
256
- const result = Reflect.apply(target[prop], receiver, args);
257
- if (result) {
258
- mutateRemoveFromRelatedRecords(this, {
259
- value: recordIdentifierFor(result),
260
- index: 0
261
- }, _SIGNAL);
262
- }
263
- return result;
264
- }
265
- case 'sort':
266
- {
267
- const result = Reflect.apply(target[prop], receiver, args);
268
- mutateSortRelatedRecords(this, result.map(recordIdentifierFor), _SIGNAL);
269
- return result;
270
- }
271
- case 'splice':
272
- {
273
- const [start, deleteCount, ...adds] = args;
274
-
275
- // detect a full replace
276
- if (start === 0 && deleteCount === this[SOURCE].length) {
277
- const newValues = extractIdentifiersFromRecords(adds);
278
- assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot replace a hasMany's state with a new state that contains duplicates.`);
279
- if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
280
- // dedupe
281
- const current = new Set(adds);
282
- const unique = Array.from(current);
283
- const newArgs = [start, deleteCount].concat(unique);
284
- const result = Reflect.apply(target[prop], receiver, newArgs);
285
- mutateReplaceRelatedRecords(this, extractIdentifiersFromRecords(unique), _SIGNAL);
286
- return result;
287
- }
288
-
289
- // else, no dedupe, error on duplicates
290
- const result = Reflect.apply(target[prop], receiver, args);
291
- mutateReplaceRelatedRecords(this, newValues, _SIGNAL);
292
- return result;
293
- }
294
- const newValues = extractIdentifiersFromRecords(adds);
295
- assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot splice a hasMany's state with a new state that contains duplicates.`);
296
- if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
297
- // dedupe
298
- const currentState = target.slice();
299
- currentState.splice(start, deleteCount);
300
- const seen = new Set(currentState);
301
- const unique = [];
302
- adds.forEach(item => {
303
- const identifier = recordIdentifierFor(item);
304
- if (!seen.has(identifier)) {
305
- seen.add(identifier);
306
- unique.push(item);
307
- }
308
- });
309
- const newArgs = [start, deleteCount, ...unique];
310
- const result = Reflect.apply(target[prop], receiver, newArgs);
311
- if (deleteCount > 0) {
312
- mutateRemoveFromRelatedRecords(this, {
313
- value: result.map(recordIdentifierFor),
314
- index: start
315
- }, _SIGNAL);
316
- }
317
- if (unique.length > 0) {
318
- mutateAddToRelatedRecords(this, {
319
- value: extractIdentifiersFromRecords(unique),
320
- index: start
321
- }, _SIGNAL);
322
- }
323
- return result;
324
- }
325
-
326
- // else, no dedupe, error on duplicates
327
- const result = Reflect.apply(target[prop], receiver, args);
328
- if (deleteCount > 0) {
329
- mutateRemoveFromRelatedRecords(this, {
330
- value: result.map(recordIdentifierFor),
331
- index: start
332
- }, _SIGNAL);
333
- }
334
- if (newValues.length > 0) {
335
- mutateAddToRelatedRecords(this, {
336
- value: newValues,
337
- index: start
338
- }, _SIGNAL);
339
- }
340
- return result;
341
- }
342
- default:
343
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
344
- {
345
- throw new Error(`unable to convert ${prop} into a transaction that updates the cache state for this record array`);
346
- }
347
- })() : {};
348
- }
349
- }
350
- notify() {
351
- const signal = this[ARRAY_SIGNAL];
352
- signal.shouldReset = true;
353
- notifyArray(this);
354
- }
355
-
356
- /**
357
- Reloads all of the records in the manyArray. If the manyArray
358
- holds a relationship that was originally fetched using a links url
359
- EmberData will revisit the original links url to repopulate the
360
- relationship.
361
- If the ManyArray holds the result of a `store.query()` reload will
362
- re-run the original query.
363
- Example
364
- ```javascript
365
- let user = store.peekRecord('user', '1')
366
- await login(user);
367
- let permissions = await user.permissions;
368
- await permissions.reload();
369
- ```
370
- @method reload
371
- @public
372
- */
373
- reload(options) {
374
- // TODO this is odd, we don't ask the store for anything else like this?
375
- return this._manager.reloadHasMany(this.key, options);
376
- }
377
-
378
- /**
379
- Saves all of the records in the `ManyArray`.
380
- Example
381
- ```javascript
382
- let inbox = await store.findRecord('inbox', '1');
383
- let messages = await inbox.messages;
384
- messages.forEach((message) => {
385
- message.isRead = true;
386
- });
387
- messages.save();
388
- ```
389
- @method save
390
- @public
391
- @return {PromiseArray} promise
392
- */
393
-
394
- /**
395
- Create a child record within the owner
396
- @method createRecord
397
- @public
398
- @param {Object} hash
399
- @return {Model} record
400
- */
401
- createRecord(hash) {
402
- const {
403
- store
404
- } = this;
405
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
406
- if (!test) {
407
- throw new Error(`Expected modelName to be set`);
408
- }
409
- })(this.modelName) : {};
410
- const record = store.createRecord(this.modelName, hash);
411
- this.push(record);
412
- return record;
413
- }
414
- destroy() {
415
- super.destroy(false);
416
- }
417
- }
418
- RelatedCollection.prototype.isAsync = false;
419
- RelatedCollection.prototype.isPolymorphic = false;
420
- RelatedCollection.prototype.identifier = null;
421
- RelatedCollection.prototype.cache = null;
422
- RelatedCollection.prototype._inverseIsAsync = false;
423
- RelatedCollection.prototype.key = '';
424
- RelatedCollection.prototype.DEPRECATED_CLASS_NAME = 'ManyArray';
425
- function assertRecordPassedToHasMany(record) {
426
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
427
- if (!test) {
428
- throw new Error(`All elements of a hasMany relationship must be instances of Model, you passed ${typeof record}`);
429
- }
430
- })(function () {
431
- try {
432
- recordIdentifierFor(record);
433
- return true;
434
- } catch {
435
- return false;
436
- }
437
- }()) : {};
438
- }
439
- function extractIdentifiersFromRecords(records) {
440
- return records.map(extractIdentifierFromRecord$1);
441
- }
442
- function extractIdentifierFromRecord$1(recordOrPromiseRecord) {
443
- assertRecordPassedToHasMany(recordOrPromiseRecord);
444
- return recordIdentifierFor(recordOrPromiseRecord);
445
- }
446
- function assertNoDuplicates(collection, target, callback, reason) {
447
- const state = target.slice();
448
- callback(state);
449
- if (state.length !== new Set(state).size) {
450
- const duplicates = state.filter((currentValue, currentIndex) => state.indexOf(currentValue) !== currentIndex);
451
- if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
452
- 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, {
453
- id: 'ember-data:deprecate-many-array-duplicates',
454
- for: 'ember-data',
455
- until: '6.0',
456
- since: {
457
- enabled: '5.3',
458
- available: '4.13'
459
- }
460
- });
461
- } else {
462
- 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- ')}`);
463
- }
464
- }
465
- }
466
- function mutateAddToRelatedRecords(collection, operationInfo, _SIGNAL) {
467
- mutate(collection, {
468
- op: 'addToRelatedRecords',
469
- record: collection.identifier,
470
- field: collection.key,
471
- ...operationInfo
472
- }, _SIGNAL);
473
- }
474
- function mutateRemoveFromRelatedRecords(collection, operationInfo, _SIGNAL) {
475
- mutate(collection, {
476
- op: 'removeFromRelatedRecords',
477
- record: collection.identifier,
478
- field: collection.key,
479
- ...operationInfo
480
- }, _SIGNAL);
481
- }
482
- function mutateReplaceRelatedRecord(collection, operationInfo, _SIGNAL) {
483
- mutate(collection, {
484
- op: 'replaceRelatedRecord',
485
- record: collection.identifier,
486
- field: collection.key,
487
- ...operationInfo
488
- }, _SIGNAL);
489
- }
490
- function mutateReplaceRelatedRecords(collection, value, _SIGNAL) {
491
- mutate(collection, {
492
- op: 'replaceRelatedRecords',
493
- record: collection.identifier,
494
- field: collection.key,
495
- value
496
- }, _SIGNAL);
497
- }
498
- function mutateSortRelatedRecords(collection, value, _SIGNAL) {
499
- mutate(collection, {
500
- op: 'sortRelatedRecords',
501
- record: collection.identifier,
502
- field: collection.key,
503
- value
504
- }, _SIGNAL);
505
- }
506
- function mutate(collection, mutation, _SIGNAL) {
507
- collection._manager.mutate(mutation);
508
- addToTransaction(_SIGNAL);
509
- }
510
50
  const PromiseObject = ObjectProxy.extend(PromiseProxyMixin);
511
51
  const deferred = /* @__PURE__ */new WeakMap();
512
52
  function deferDecorator(proto, prop, desc) {
@@ -896,16 +436,18 @@ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
896
436
  }
897
437
  if (parentDefinition.isPolymorphic) {
898
438
  const meta = store.schema.fields(addedIdentifier)?.get(parentDefinition.inverseKey);
899
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
900
- if (!test) {
901
- throw new Error(`Expected the schema for the field ${parentDefinition.inverseKey} on ${addedIdentifier.type} to be for a legacy relationship`);
902
- }
903
- })(!meta || meta.kind === 'belongsTo' || meta.kind === 'hasMany') : {};
904
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
905
- if (!test) {
906
- throw new Error(`The schema for the relationship '${parentDefinition.inverseKey}' on '${addedIdentifier.type}' type does not implement '${parentDefinition.type}' and thus cannot be assigned to the '${parentDefinition.key}' relationship in '${parentIdentifier.type}'. The definition should specify 'as: "${parentDefinition.type}"' in options.`);
907
- }
908
- })(meta?.options.as === parentDefinition.type) : {};
439
+ if (meta) {
440
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
441
+ if (!test) {
442
+ throw new Error(`Expected the schema for the field ${parentDefinition.inverseKey} on ${addedIdentifier.type} to be for a legacy relationship`);
443
+ }
444
+ })(meta.kind === 'belongsTo' || meta.kind === 'hasMany') : {};
445
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
446
+ if (!test) {
447
+ throw new Error(`The schema for the relationship '${parentDefinition.inverseKey}' on '${addedIdentifier.type}' type does not implement '${parentDefinition.type}' and thus cannot be assigned to the '${parentDefinition.key}' relationship in '${parentIdentifier.type}'. The definition should specify 'as: "${parentDefinition.type}"' in options.`);
448
+ }
449
+ })(meta?.options?.as === parentDefinition.type) : {};
450
+ }
909
451
  }
910
452
  };
911
453
  }
@@ -995,9 +537,9 @@ class HasManyReference {
995
537
  * @public
996
538
  */
997
539
  get identifiers() {
540
+ ensureRefCanSubscribe(this);
998
541
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
999
- this._ref; // consume the tracked prop
1000
-
542
+ this._ref;
1001
543
  const resource = this._resource();
1002
544
  const map = this.___relatedTokenMap;
1003
545
  this.___relatedTokenMap = new Map();
@@ -1379,10 +921,7 @@ class HasManyReference {
1379
921
  */
1380
922
  value() {
1381
923
  const support = LEGACY_SUPPORT.get(this.___identifier);
1382
- const loaded = this._isLoaded();
1383
- if (!loaded) {
1384
- // subscribe to changes
1385
- // for when we are not loaded yet
924
+ if (!ensureRefCanSubscribe(this)) {
1386
925
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
1387
926
  this._ref;
1388
927
  return null;
@@ -1502,6 +1041,26 @@ function isMaybeResource(object) {
1502
1041
  const keys = Object.keys(object).filter(k => k !== 'id' && k !== 'type' && k !== 'lid');
1503
1042
  return keys.length > 0;
1504
1043
  }
1044
+ function ensureRefCanSubscribe(rel) {
1045
+ const loaded = rel._isLoaded();
1046
+ if (!loaded) {
1047
+ // subscribe to changes
1048
+ // for when we are not loaded yet
1049
+ //
1050
+ // because the graph optimizes the case where a relationship has never been subscribed,
1051
+ // we force accessed to be true here. When we make the graph public we should create a
1052
+ // subscribe/unsubscribe API
1053
+ const edge = rel.graph.get(rel.___identifier, rel.key);
1054
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1055
+ if (!test) {
1056
+ throw new Error(`Expected a hasMany relationship for ${rel.___identifier.type}:${rel.key}`);
1057
+ }
1058
+ })('accessed' in edge) : {};
1059
+ edge.accessed = true;
1060
+ return false;
1061
+ }
1062
+ return true;
1063
+ }
1505
1064
  function isResourceIdentiferWithRelatedLinks(value) {
1506
1065
  return Boolean(value && value.links && value.links.related);
1507
1066
  }
@@ -2246,6 +1805,7 @@ class LegacySupport {
2246
1805
  isPolymorphic: definition.isPolymorphic,
2247
1806
  isAsync: definition.isAsync,
2248
1807
  _inverseIsAsync: definition.inverseIsAsync,
1808
+ // @ts-expect-error Typescript doesn't have a way for us to thread the generic backwards so it infers unknown instead of T
2249
1809
  manager: this,
2250
1810
  isLoaded: !definition.isAsync,
2251
1811
  allowMutation: true
@@ -3216,30 +2776,35 @@ function createSnapshot() {
3216
2776
  return store._fetchManager.createSnapshot(recordIdentifierFor$1(this));
3217
2777
  }
3218
2778
  function notifyChanges(identifier, value, key, record, store) {
3219
- if (value === 'attributes') {
3220
- if (key) {
3221
- notifyAttribute(store, identifier, key, record);
3222
- } else {
3223
- record.eachAttribute(name => {
3224
- notifyAttribute(store, identifier, name, record);
3225
- });
3226
- }
3227
- } else if (value === 'relationships') {
3228
- if (key) {
3229
- const meta = record.constructor.relationshipsByName.get(key);
3230
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
3231
- if (!test) {
3232
- throw new Error(`Expected to find a relationship for ${key} on ${identifier.type}`);
3233
- }
3234
- })(meta) : {};
3235
- notifyRelationship(identifier, key, record, meta);
3236
- } else {
3237
- record.eachRelationship((name, meta) => {
3238
- notifyRelationship(identifier, name, record, meta);
3239
- });
3240
- }
3241
- } else if (value === 'identity') {
3242
- record.notifyPropertyChange('id');
2779
+ switch (value) {
2780
+ case 'added':
2781
+ case 'attributes':
2782
+ if (key) {
2783
+ notifyAttribute(store, identifier, key, record);
2784
+ } else {
2785
+ record.eachAttribute(name => {
2786
+ notifyAttribute(store, identifier, name, record);
2787
+ });
2788
+ }
2789
+ break;
2790
+ case 'relationships':
2791
+ if (key) {
2792
+ const meta = record.constructor.relationshipsByName.get(key);
2793
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2794
+ if (!test) {
2795
+ throw new Error(`Expected to find a relationship for ${key} on ${identifier.type}`);
2796
+ }
2797
+ })(meta) : {};
2798
+ notifyRelationship(identifier, key, record, meta);
2799
+ } else {
2800
+ record.eachRelationship((name, meta) => {
2801
+ notifyRelationship(identifier, name, record, meta);
2802
+ });
2803
+ }
2804
+ break;
2805
+ case 'identity':
2806
+ record.notifyPropertyChange('id');
2807
+ break;
3243
2808
  }
3244
2809
  }
3245
2810
  function notifyRelationship(identifier, key, record, meta) {
@@ -3290,44 +2855,6 @@ function isInvalidError(error) {
3290
2855
  return !!error && error instanceof Error && 'isAdapterError' in error && error.isAdapterError === true && 'code' in error && error.code === 'InvalidError';
3291
2856
  }
3292
2857
 
3293
- /**
3294
- * A decorator that caches a getter while
3295
- * providing the ability to bust that cache
3296
- * when we so choose in a way that notifies
3297
- * tracking systems.
3298
- *
3299
- * @internal
3300
- */
3301
- function tagged(_target, key, desc) {
3302
- // eslint-disable-next-line @typescript-eslint/unbound-method
3303
- const getter = desc.get;
3304
- // eslint-disable-next-line @typescript-eslint/unbound-method
3305
- const setter = desc.set;
3306
- desc.get = function () {
3307
- const signal = getSignal(this, key, true);
3308
- subscribe(signal);
3309
- if (signal.shouldReset) {
3310
- signal.shouldReset = false;
3311
- signal.lastValue = getter.call(this);
3312
- }
3313
- return signal.lastValue;
3314
- };
3315
- desc.set = function (v) {
3316
- getSignal(this, key, true); // ensure signal is setup in case we want to use it.
3317
- // probably notify here but not yet.
3318
- setter.call(this, v);
3319
- };
3320
- compat(desc);
3321
- return desc;
3322
- }
3323
- function notifySignal(obj, key) {
3324
- const signal = peekSignal(obj, key);
3325
- if (signal) {
3326
- signal.shouldReset = true;
3327
- addToTransaction(signal);
3328
- }
3329
- }
3330
-
3331
2858
  /**
3332
2859
  Historically EmberData managed a state machine
3333
2860
  for each record, the localState for which
@@ -3504,7 +3031,7 @@ class RecordState {
3504
3031
  return !this.isLoaded && this.pendingCount > 0 && this.fulfilledCount === 0;
3505
3032
  }
3506
3033
  static {
3507
- decorateMethodV2(this.prototype, "isLoading", [tagged]);
3034
+ decorateMethodV2(this.prototype, "isLoading", [subscribed]);
3508
3035
  }
3509
3036
  get isLoaded() {
3510
3037
  if (this.isNew) {
@@ -3513,7 +3040,7 @@ class RecordState {
3513
3040
  return this.fulfilledCount > 0 || !this.isEmpty;
3514
3041
  }
3515
3042
  static {
3516
- decorateMethodV2(this.prototype, "isLoaded", [tagged]);
3043
+ decorateMethodV2(this.prototype, "isLoaded", [subscribed]);
3517
3044
  }
3518
3045
  get isSaved() {
3519
3046
  const rd = this.cache;
@@ -3531,7 +3058,7 @@ class RecordState {
3531
3058
  return true;
3532
3059
  }
3533
3060
  static {
3534
- decorateMethodV2(this.prototype, "isSaved", [tagged]);
3061
+ decorateMethodV2(this.prototype, "isSaved", [subscribed]);
3535
3062
  }
3536
3063
  get isEmpty() {
3537
3064
  const rd = this.cache;
@@ -3545,7 +3072,7 @@ class RecordState {
3545
3072
  return !this.isNew && rd.isEmpty(this.identifier);
3546
3073
  }
3547
3074
  static {
3548
- decorateMethodV2(this.prototype, "isEmpty", [tagged]);
3075
+ decorateMethodV2(this.prototype, "isEmpty", [subscribed]);
3549
3076
  }
3550
3077
  get isNew() {
3551
3078
  const rd = this.cache;
@@ -3557,7 +3084,7 @@ class RecordState {
3557
3084
  return rd.isNew(this.identifier);
3558
3085
  }
3559
3086
  static {
3560
- decorateMethodV2(this.prototype, "isNew", [tagged]);
3087
+ decorateMethodV2(this.prototype, "isNew", [subscribed]);
3561
3088
  }
3562
3089
  get isDeleted() {
3563
3090
  const rd = this.cache;
@@ -3569,13 +3096,13 @@ class RecordState {
3569
3096
  return rd.isDeleted(this.identifier);
3570
3097
  }
3571
3098
  static {
3572
- decorateMethodV2(this.prototype, "isDeleted", [tagged]);
3099
+ decorateMethodV2(this.prototype, "isDeleted", [subscribed]);
3573
3100
  }
3574
3101
  get isValid() {
3575
3102
  return this.record.errors.length === 0;
3576
3103
  }
3577
3104
  static {
3578
- decorateMethodV2(this.prototype, "isValid", [tagged]);
3105
+ decorateMethodV2(this.prototype, "isValid", [subscribed]);
3579
3106
  }
3580
3107
  get isDirty() {
3581
3108
  const rd = this.cache;
@@ -3585,7 +3112,7 @@ class RecordState {
3585
3112
  return this.isDeleted || this.isNew || rd.hasChangedAttrs(this.identifier);
3586
3113
  }
3587
3114
  static {
3588
- decorateMethodV2(this.prototype, "isDirty", [tagged]);
3115
+ decorateMethodV2(this.prototype, "isDirty", [subscribed]);
3589
3116
  }
3590
3117
  get isError() {
3591
3118
  const errorReq = this._errorRequests[this._errorRequests.length - 1];
@@ -3596,7 +3123,7 @@ class RecordState {
3596
3123
  }
3597
3124
  }
3598
3125
  static {
3599
- decorateMethodV2(this.prototype, "isError", [tagged]);
3126
+ decorateMethodV2(this.prototype, "isError", [subscribed]);
3600
3127
  }
3601
3128
  get adapterError() {
3602
3129
  const request = this._lastError;
@@ -3606,7 +3133,7 @@ class RecordState {
3606
3133
  return request.state === 'rejected' && request.response.data;
3607
3134
  }
3608
3135
  static {
3609
- decorateMethodV2(this.prototype, "adapterError", [tagged]);
3136
+ decorateMethodV2(this.prototype, "adapterError", [subscribed]);
3610
3137
  }
3611
3138
  get isPreloaded() {
3612
3139
  return !this.isEmpty && this.isLoading;
@@ -3838,9 +3365,8 @@ class Model extends EmberObject {
3838
3365
  ```javascript
3839
3366
  let record = store.createRecord('model');
3840
3367
  record.isLoaded; // true
3841
- store.findRecord('model', 1).then(function(model) {
3842
- model.isLoaded; // true
3843
- });
3368
+ const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' }));
3369
+ model.isLoaded;
3844
3370
  ```
3845
3371
  @property isLoaded
3846
3372
  @public
@@ -3863,11 +3389,10 @@ class Model extends EmberObject {
3863
3389
  ```javascript
3864
3390
  let record = store.createRecord('model');
3865
3391
  record.hasDirtyAttributes; // true
3866
- store.findRecord('model', 1).then(function(model) {
3867
- model.hasDirtyAttributes; // false
3868
- model.set('foo', 'some value');
3869
- model.hasDirtyAttributes; // true
3870
- });
3392
+ const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' }));
3393
+ model.hasDirtyAttributes; // false
3394
+ model.foo = 'some value';
3395
+ model.hasDirtyAttributes; // true
3871
3396
  ```
3872
3397
  @since 1.13.0
3873
3398
  @property hasDirtyAttributes
@@ -4068,9 +3593,8 @@ class Model extends EmberObject {
4068
3593
  ```javascript
4069
3594
  let record = store.createRecord('model');
4070
3595
  record.id; // null
4071
- store.findRecord('model', 1).then(function(model) {
4072
- model.id; // '1'
4073
- });
3596
+ const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' }));
3597
+ model.id; // '1'
4074
3598
  ```
4075
3599
  @property id
4076
3600
  @public
@@ -4090,7 +3614,7 @@ class Model extends EmberObject {
4090
3614
  return recordIdentifierFor$1(this).id;
4091
3615
  }
4092
3616
  static {
4093
- decorateMethodV2(this.prototype, "id", [tagged]);
3617
+ decorateMethodV2(this.prototype, "id", [subscribed]);
4094
3618
  }
4095
3619
  set id(id) {
4096
3620
  const normalizedId = coerceId(id);
@@ -4130,7 +3654,7 @@ class Model extends EmberObject {
4130
3654
  return this.___recordState;
4131
3655
  }
4132
3656
  static {
4133
- decorateMethodV2(this.prototype, "currentState", [tagged]);
3657
+ decorateMethodV2(this.prototype, "currentState", [subscribed]);
4134
3658
  }
4135
3659
  set currentState(_v) {
4136
3660
  throw new Error('cannot set currentState');
@@ -5143,7 +4667,7 @@ class Model extends EmberObject {
5143
4667
  if (isAttributeSchema(meta)) {
5144
4668
  macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5145
4669
  if (!test) {
5146
- throw new Error("You may not set `id` as an attribute on your model. Please remove any lines that look like: `id: attr('<type>')` from " + this.toString());
4670
+ throw new Error("You may not set 'id' as an attribute on your model. Please remove any lines that look like: `id: attr('<type>')` from " + this.toString());
5147
4671
  }
5148
4672
  })(name !== 'id') : {};
5149
4673
 
@@ -5378,4 +4902,4 @@ function isRelationshipSchema(meta) {
5378
4902
  function isAttributeSchema(meta) {
5379
4903
  return typeof meta === 'object' && meta !== null && 'kind' in meta && meta.kind === 'attribute';
5380
4904
  }
5381
- export { Errors as E, LEGACY_SUPPORT as L, Model as M, PromiseBelongsTo as P, RelatedCollection as R, PromiseManyArray as a, save as b, reload as c, destroyRecord as d, deleteRecord as e, RecordState as f, changedAttributes as g, hasMany as h, belongsTo as i, createSnapshot as j, isElementDescriptor as k, lookupLegacySupport as l, normalizeModelName as n, rollbackAttributes as r, serialize as s, unloadRecord as u };
4905
+ export { Errors as E, LEGACY_SUPPORT as L, Model as M, PromiseBelongsTo as P, RecordState as R, PromiseManyArray as a, save as b, reload as c, destroyRecord as d, deleteRecord as e, changedAttributes as f, belongsTo as g, hasMany as h, createSnapshot as i, isElementDescriptor as j, lookupLegacySupport as l, normalizeModelName as n, rollbackAttributes as r, serialize as s, unloadRecord as u };