@ember-data/model 4.13.0-alpha.3 → 4.13.0-alpha.5

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 (58) 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-CshPdrqR.js → has-many-iejadOqh.js} +1 -1
  6. package/dist/has-many-iejadOqh.js.map +1 -0
  7. package/dist/{hooks-DCYCaSEL.js → hooks-I41sUeI8.js} +2 -2
  8. package/dist/{hooks-DCYCaSEL.js.map → hooks-I41sUeI8.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/{legacy-relationships-support-D5m0xTYg.js → legacy-relationships-support-B9S5UYiI.js} +110 -549
  13. package/dist/legacy-relationships-support-B9S5UYiI.js.map +1 -0
  14. package/dist/migration-support.js +2 -2
  15. package/dist/migration-support.js.map +1 -1
  16. package/dist/{schema-provider-m94yB7iS.js → schema-provider-CUU5ltjo.js} +1 -1
  17. package/dist/{schema-provider-m94yB7iS.js.map → schema-provider-CUU5ltjo.js.map} +1 -1
  18. package/logos/NCC-1701-a-gold.svg +4 -0
  19. package/logos/NCC-1701-a-gold_100.svg +1 -0
  20. package/logos/NCC-1701-a-gold_base-64.txt +1 -0
  21. package/logos/README.md +4 -0
  22. package/logos/docs-badge.svg +2 -0
  23. package/logos/github-header.svg +444 -0
  24. package/logos/social1.png +0 -0
  25. package/logos/social2.png +0 -0
  26. package/logos/warp-drive-logo-dark.svg +4 -0
  27. package/logos/warp-drive-logo-gold.svg +4 -0
  28. package/package.json +41 -63
  29. package/unstable-preview-types/-private/belongs-to.d.ts +1 -0
  30. package/unstable-preview-types/-private/belongs-to.d.ts.map +1 -1
  31. package/unstable-preview-types/-private/legacy-relationships-support.d.ts +1 -1
  32. package/unstable-preview-types/-private/legacy-relationships-support.d.ts.map +1 -1
  33. package/unstable-preview-types/-private/model.d.ts +9 -11
  34. package/unstable-preview-types/-private/model.d.ts.map +1 -1
  35. package/unstable-preview-types/-private/notify-changes.d.ts.map +1 -1
  36. package/unstable-preview-types/-private/promise-many-array.d.ts +1 -2
  37. package/unstable-preview-types/-private/promise-many-array.d.ts.map +1 -1
  38. package/unstable-preview-types/-private/promise-proxy-base.d.ts +5 -0
  39. package/unstable-preview-types/-private/promise-proxy-base.d.ts.map +1 -0
  40. package/unstable-preview-types/-private/record-state.d.ts +1 -1
  41. package/unstable-preview-types/-private/references/has-many.d.ts +1 -1
  42. package/unstable-preview-types/-private/references/has-many.d.ts.map +1 -1
  43. package/unstable-preview-types/-private/relationship-meta.d.ts +2 -0
  44. package/unstable-preview-types/-private/relationship-meta.d.ts.map +1 -1
  45. package/unstable-preview-types/-private/type-utils.d.ts +1 -1
  46. package/unstable-preview-types/-private/type-utils.d.ts.map +1 -1
  47. package/unstable-preview-types/-private.d.ts +1 -1
  48. package/unstable-preview-types/-private.d.ts.map +1 -1
  49. package/unstable-preview-types/index.d.ts +19 -19
  50. package/unstable-preview-types/index.d.ts.map +1 -1
  51. package/unstable-preview-types/migration-support.d.ts +7 -0
  52. package/unstable-preview-types/migration-support.d.ts.map +1 -1
  53. package/dist/has-many-CshPdrqR.js.map +0 -1
  54. package/dist/legacy-relationships-support-D5m0xTYg.js.map +0 -1
  55. package/unstable-preview-types/-private/many-array.d.ts +0 -196
  56. package/unstable-preview-types/-private/many-array.d.ts.map +0 -1
  57. /package/{ember-data-logo-dark.svg → logos/ember-data-logo-dark.svg} +0 -0
  58. /package/{ember-data-logo-light.svg → logos/ember-data-logo-light.svg} +0 -0
@@ -2,16 +2,17 @@ import { deprecate, warn } from '@ember/debug';
2
2
  import { dasherize, singularize } from '@ember-data/request-utils/string';
3
3
  import { macroCondition, getGlobalConfig, importSync, dependencySatisfies } from '@embroider/macros';
4
4
  import { upgradeStore } from '@ember-data/legacy-compat/-private';
5
- import { LiveArray, MUTATE, SOURCE, recordIdentifierFor, ARRAY_SIGNAL, notifyArray, isStableIdentifier, peekCache, coerceId, storeFor as storeFor$1, fastPush } from '@ember-data/store/-private';
5
+ import { peekCache, recordIdentifierFor as recordIdentifierFor$1, coerceId, storeFor as storeFor$1, SOURCE, fastPush, isStableIdentifier, RelatedCollection } from '@ember-data/store/-private';
6
6
  import { getOrSetGlobal } from '@warp-drive/core-types/-private';
7
- import { addToTransaction, defineSignal, peekSignal, getSignal, subscribe } from '@ember-data/tracking/-private';
7
+ import { EnableHydration } from '@warp-drive/core-types/request';
8
8
  import EmberObject, { computed, get } from '@ember/object';
9
9
  import { cached, compat } from '@ember-data/tracking';
10
10
  import PromiseProxyMixin from '@ember/object/promise-proxy-mixin';
11
11
  import ObjectProxy from '@ember/object/proxy';
12
12
  import ArrayMixin, { NativeArray, A } from '@ember/array';
13
13
  import Ember from 'ember';
14
- import { recordIdentifierFor as recordIdentifierFor$1, storeFor } from '@ember-data/store';
14
+ import { defineSignal, peekSignal, addToTransaction, getSignal, subscribe } from '@ember-data/tracking/-private';
15
+ import { recordIdentifierFor, storeFor } from '@ember-data/store';
15
16
  import { RecordStore } from '@warp-drive/core-types/symbols';
16
17
  import ArrayProxy from '@ember/array/proxy';
17
18
  import { mapBy, not } from '@ember/object/computed';
@@ -47,491 +48,6 @@ function normalizeModelName(type) {
47
48
  }
48
49
  return type;
49
50
  }
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 uniqueIdentifiers = Array.from(new Set(newValues));
284
- const newArgs = [start, deleteCount].concat(unique);
285
- const result = Reflect.apply(target[prop], receiver, newArgs);
286
- mutateReplaceRelatedRecords(this, uniqueIdentifiers, _SIGNAL);
287
- return result;
288
- }
289
-
290
- // else, no dedupe, error on duplicates
291
- const result = Reflect.apply(target[prop], receiver, args);
292
- mutateReplaceRelatedRecords(this, newValues, _SIGNAL);
293
- return result;
294
- }
295
- const newValues = extractIdentifiersFromRecords(adds);
296
- assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot splice a hasMany's state with a new state that contains duplicates.`);
297
- if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
298
- // dedupe
299
- const currentState = target.slice();
300
- currentState.splice(start, deleteCount);
301
- const seen = new Set(currentState);
302
- const unique = [];
303
- adds.forEach(item => {
304
- const identifier = recordIdentifierFor(item);
305
- if (!seen.has(identifier)) {
306
- seen.add(identifier);
307
- unique.push(item);
308
- }
309
- });
310
- const newArgs = [start, deleteCount, ...unique];
311
- const result = Reflect.apply(target[prop], receiver, newArgs);
312
- if (deleteCount > 0) {
313
- mutateRemoveFromRelatedRecords(this, {
314
- value: result.map(recordIdentifierFor),
315
- index: start
316
- }, _SIGNAL);
317
- }
318
- if (unique.length > 0) {
319
- mutateAddToRelatedRecords(this, {
320
- value: extractIdentifiersFromRecords(unique),
321
- index: start
322
- }, _SIGNAL);
323
- }
324
- return result;
325
- }
326
-
327
- // else, no dedupe, error on duplicates
328
- const result = Reflect.apply(target[prop], receiver, args);
329
- if (deleteCount > 0) {
330
- mutateRemoveFromRelatedRecords(this, {
331
- value: result.map(recordIdentifierFor),
332
- index: start
333
- }, _SIGNAL);
334
- }
335
- if (newValues.length > 0) {
336
- mutateAddToRelatedRecords(this, {
337
- value: newValues,
338
- index: start
339
- }, _SIGNAL);
340
- }
341
- return result;
342
- }
343
- default:
344
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
345
- {
346
- throw new Error(`unable to convert ${prop} into a transaction that updates the cache state for this record array`);
347
- }
348
- })() : {};
349
- }
350
- }
351
- notify() {
352
- const signal = this[ARRAY_SIGNAL];
353
- signal.shouldReset = true;
354
- notifyArray(this);
355
- }
356
-
357
- /**
358
- Reloads all of the records in the manyArray. If the manyArray
359
- holds a relationship that was originally fetched using a links url
360
- EmberData will revisit the original links url to repopulate the
361
- relationship.
362
- If the ManyArray holds the result of a `store.query()` reload will
363
- re-run the original query.
364
- Example
365
- ```javascript
366
- let user = store.peekRecord('user', '1')
367
- await login(user);
368
- let permissions = await user.permissions;
369
- await permissions.reload();
370
- ```
371
- @method reload
372
- @public
373
- */
374
- reload(options) {
375
- // TODO this is odd, we don't ask the store for anything else like this?
376
- return this._manager.reloadHasMany(this.key, options);
377
- }
378
-
379
- /**
380
- Saves all of the records in the `ManyArray`.
381
- Example
382
- ```javascript
383
- let inbox = await store.findRecord('inbox', '1');
384
- let messages = await inbox.messages;
385
- messages.forEach((message) => {
386
- message.isRead = true;
387
- });
388
- messages.save();
389
- ```
390
- @method save
391
- @public
392
- @return {PromiseArray} promise
393
- */
394
-
395
- /**
396
- Create a child record within the owner
397
- @method createRecord
398
- @public
399
- @param {Object} hash
400
- @return {Model} record
401
- */
402
- createRecord(hash) {
403
- const {
404
- store
405
- } = this;
406
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
407
- if (!test) {
408
- throw new Error(`Expected modelName to be set`);
409
- }
410
- })(this.modelName) : {};
411
- const record = store.createRecord(this.modelName, hash);
412
- this.push(record);
413
- return record;
414
- }
415
- destroy() {
416
- super.destroy(false);
417
- }
418
- }
419
- RelatedCollection.prototype.isAsync = false;
420
- RelatedCollection.prototype.isPolymorphic = false;
421
- RelatedCollection.prototype.identifier = null;
422
- RelatedCollection.prototype.cache = null;
423
- RelatedCollection.prototype._inverseIsAsync = false;
424
- RelatedCollection.prototype.key = '';
425
- RelatedCollection.prototype.DEPRECATED_CLASS_NAME = 'ManyArray';
426
- function assertRecordPassedToHasMany(record) {
427
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
428
- if (!test) {
429
- throw new Error(`All elements of a hasMany relationship must be instances of Model, you passed ${typeof record}`);
430
- }
431
- })(function () {
432
- try {
433
- recordIdentifierFor(record);
434
- return true;
435
- } catch {
436
- return false;
437
- }
438
- }()) : {};
439
- }
440
- function extractIdentifiersFromRecords(records) {
441
- return records.map(extractIdentifierFromRecord$1);
442
- }
443
- function extractIdentifierFromRecord$1(recordOrPromiseRecord) {
444
- if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_PROMISE_PROXIES)) {
445
- if (isPromiseRecord$1(recordOrPromiseRecord)) {
446
- const content = recordOrPromiseRecord.content;
447
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
448
- if (!test) {
449
- throw new Error('You passed in a promise that did not originate from an EmberData relationship. You can only pass promises that come from a belongsTo relationship.');
450
- }
451
- })(content !== undefined && content !== null) : {};
452
- deprecate(`You passed in a PromiseProxy to a Relationship API that now expects a resolved value. await the value before setting it.`, false, {
453
- id: 'ember-data:deprecate-promise-proxies',
454
- until: '5.0',
455
- since: {
456
- enabled: '4.7',
457
- available: '4.7'
458
- },
459
- for: 'ember-data'
460
- });
461
- assertRecordPassedToHasMany(content);
462
- return recordIdentifierFor(content);
463
- }
464
- }
465
- assertRecordPassedToHasMany(recordOrPromiseRecord);
466
- return recordIdentifierFor(recordOrPromiseRecord);
467
- }
468
- function isPromiseRecord$1(record) {
469
- return Boolean(typeof record === 'object' && record && 'then' in record);
470
- }
471
- function assertNoDuplicates(collection, target, callback, reason) {
472
- const state = target.slice();
473
- callback(state);
474
- if (state.length !== new Set(state).size) {
475
- const duplicates = state.filter((currentValue, currentIndex) => state.indexOf(currentValue) !== currentIndex);
476
- if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
477
- 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- ')}`, /* inline-macro-config */getGlobalConfig().WarpDrive.deprecations.DISABLE_6X_DEPRECATIONS, {
478
- id: 'ember-data:deprecate-many-array-duplicates',
479
- for: 'ember-data',
480
- until: '6.0',
481
- since: {
482
- enabled: '5.3',
483
- available: '4.13'
484
- }
485
- });
486
- } else {
487
- 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- ')}`);
488
- }
489
- }
490
- }
491
- function mutateAddToRelatedRecords(collection, operationInfo, _SIGNAL) {
492
- mutate(collection, {
493
- op: 'addToRelatedRecords',
494
- record: collection.identifier,
495
- field: collection.key,
496
- ...operationInfo
497
- }, _SIGNAL);
498
- }
499
- function mutateRemoveFromRelatedRecords(collection, operationInfo, _SIGNAL) {
500
- mutate(collection, {
501
- op: 'removeFromRelatedRecords',
502
- record: collection.identifier,
503
- field: collection.key,
504
- ...operationInfo
505
- }, _SIGNAL);
506
- }
507
- function mutateReplaceRelatedRecord(collection, operationInfo, _SIGNAL) {
508
- mutate(collection, {
509
- op: 'replaceRelatedRecord',
510
- record: collection.identifier,
511
- field: collection.key,
512
- ...operationInfo
513
- }, _SIGNAL);
514
- }
515
- function mutateReplaceRelatedRecords(collection, value, _SIGNAL) {
516
- mutate(collection, {
517
- op: 'replaceRelatedRecords',
518
- record: collection.identifier,
519
- field: collection.key,
520
- value
521
- }, _SIGNAL);
522
- }
523
- function mutateSortRelatedRecords(collection, value, _SIGNAL) {
524
- mutate(collection, {
525
- op: 'sortRelatedRecords',
526
- record: collection.identifier,
527
- field: collection.key,
528
- value
529
- }, _SIGNAL);
530
- }
531
- function mutate(collection, mutation, _SIGNAL) {
532
- collection._manager.mutate(mutation);
533
- addToTransaction(_SIGNAL);
534
- }
535
51
  const PromiseObject = ObjectProxy.extend(PromiseProxyMixin);
536
52
  const deferred = /* @__PURE__ */new WeakMap();
537
53
  function deferDecorator(proto, prop, desc) {
@@ -1433,7 +949,7 @@ function rollbackAttributes() {
1433
949
  isNew
1434
950
  } = currentState;
1435
951
  this[RecordStore]._join(() => {
1436
- peekCache(this).rollbackAttrs(recordIdentifierFor$1(this));
952
+ peekCache(this).rollbackAttrs(recordIdentifierFor(this));
1437
953
  this.errors.clear();
1438
954
  currentState.cleanErrorRequests();
1439
955
  if (isNew) {
@@ -1456,7 +972,7 @@ function hasMany(prop) {
1456
972
  function reload(options = {}) {
1457
973
  options.isReloading = true;
1458
974
  options.reload = true;
1459
- const identifier = recordIdentifierFor$1(this);
975
+ const identifier = recordIdentifierFor(this);
1460
976
  macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1461
977
  if (!test) {
1462
978
  throw new Error(`You cannot reload a record without an ID`);
@@ -1481,7 +997,7 @@ function reload(options = {}) {
1481
997
  return promise;
1482
998
  }
1483
999
  function changedAttributes() {
1484
- return peekCache(this).changedAttrs(recordIdentifierFor$1(this));
1000
+ return peekCache(this).changedAttrs(recordIdentifierFor(this));
1485
1001
  }
1486
1002
  function serialize(options) {
1487
1003
  upgradeStore(this[RecordStore]);
@@ -1530,33 +1046,38 @@ function createSnapshot() {
1530
1046
  }
1531
1047
 
1532
1048
  // @ts-expect-error Typescript isn't able to curry narrowed args that are divorced from each other.
1533
- return store._fetchManager.createSnapshot(recordIdentifierFor$1(this));
1049
+ return store._fetchManager.createSnapshot(recordIdentifierFor(this));
1534
1050
  }
1535
1051
  function notifyChanges(identifier, value, key, record, store) {
1536
- if (value === 'attributes') {
1537
- if (key) {
1538
- notifyAttribute(store, identifier, key, record);
1539
- } else {
1540
- record.eachAttribute(name => {
1541
- notifyAttribute(store, identifier, name, record);
1542
- });
1543
- }
1544
- } else if (value === 'relationships') {
1545
- if (key) {
1546
- const meta = record.constructor.relationshipsByName.get(key);
1547
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1548
- if (!test) {
1549
- throw new Error(`Expected to find a relationship for ${key} on ${identifier.type}`);
1550
- }
1551
- })(meta) : {};
1552
- notifyRelationship(identifier, key, record, meta);
1553
- } else {
1554
- record.eachRelationship((name, meta) => {
1555
- notifyRelationship(identifier, name, record, meta);
1556
- });
1557
- }
1558
- } else if (value === 'identity') {
1559
- record.notifyPropertyChange('id');
1052
+ switch (value) {
1053
+ case 'added':
1054
+ case 'attributes':
1055
+ if (key) {
1056
+ notifyAttribute(store, identifier, key, record);
1057
+ } else {
1058
+ record.eachAttribute(name => {
1059
+ notifyAttribute(store, identifier, name, record);
1060
+ });
1061
+ }
1062
+ break;
1063
+ case 'relationships':
1064
+ if (key) {
1065
+ const meta = record.constructor.relationshipsByName.get(key);
1066
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1067
+ if (!test) {
1068
+ throw new Error(`Expected to find a relationship for ${key} on ${identifier.type}`);
1069
+ }
1070
+ })(meta) : {};
1071
+ notifyRelationship(identifier, key, record, meta);
1072
+ } else {
1073
+ record.eachRelationship((name, meta) => {
1074
+ notifyRelationship(identifier, name, record, meta);
1075
+ });
1076
+ }
1077
+ break;
1078
+ case 'identity':
1079
+ record.notifyPropertyChange('id');
1080
+ break;
1560
1081
  }
1561
1082
  }
1562
1083
  function notifyRelationship(identifier, key, record, meta) {
@@ -1687,7 +1208,7 @@ root
1687
1208
  class RecordState {
1688
1209
  constructor(record) {
1689
1210
  const store = storeFor(record);
1690
- const identity = recordIdentifierFor(record);
1211
+ const identity = recordIdentifierFor$1(record);
1691
1212
  this.identifier = identity;
1692
1213
  this.record = record;
1693
1214
  this.cache = store.cache;
@@ -2155,7 +1676,7 @@ class Model extends EmberObject {
2155
1676
 
2156
1677
  // @ts-expect-error destroy should not return a value, but ember's types force it to
2157
1678
  destroy() {
2158
- const identifier = recordIdentifierFor$1(this);
1679
+ const identifier = recordIdentifierFor(this);
2159
1680
  this.___recordState?.destroy();
2160
1681
  const store = storeFor(this);
2161
1682
  store.notifications.unsubscribe(this.___private_notifications);
@@ -2220,9 +1741,8 @@ class Model extends EmberObject {
2220
1741
  ```javascript
2221
1742
  let record = store.createRecord('model');
2222
1743
  record.isLoaded; // true
2223
- store.findRecord('model', 1).then(function(model) {
2224
- model.isLoaded; // true
2225
- });
1744
+ const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' }));
1745
+ model.isLoaded;
2226
1746
  ```
2227
1747
  @property isLoaded
2228
1748
  @public
@@ -2245,11 +1765,10 @@ class Model extends EmberObject {
2245
1765
  ```javascript
2246
1766
  let record = store.createRecord('model');
2247
1767
  record.hasDirtyAttributes; // true
2248
- store.findRecord('model', 1).then(function(model) {
2249
- model.hasDirtyAttributes; // false
2250
- model.set('foo', 'some value');
2251
- model.hasDirtyAttributes; // true
2252
- });
1768
+ const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' }));
1769
+ model.hasDirtyAttributes; // false
1770
+ model.foo = 'some value';
1771
+ model.hasDirtyAttributes; // true
2253
1772
  ```
2254
1773
  @since 1.13.0
2255
1774
  @property hasDirtyAttributes
@@ -2450,9 +1969,8 @@ class Model extends EmberObject {
2450
1969
  ```javascript
2451
1970
  let record = store.createRecord('model');
2452
1971
  record.id; // null
2453
- store.findRecord('model', 1).then(function(model) {
2454
- model.id; // '1'
2455
- });
1972
+ const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' }));
1973
+ model.id; // '1'
2456
1974
  ```
2457
1975
  @property id
2458
1976
  @public
@@ -2464,19 +1982,19 @@ class Model extends EmberObject {
2464
1982
  // object is real.
2465
1983
  if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
2466
1984
  try {
2467
- return recordIdentifierFor$1(this).id;
1985
+ return recordIdentifierFor(this).id;
2468
1986
  } catch {
2469
1987
  return null;
2470
1988
  }
2471
1989
  }
2472
- return recordIdentifierFor$1(this).id;
1990
+ return recordIdentifierFor(this).id;
2473
1991
  }
2474
1992
  static {
2475
1993
  decorateMethodV2(this.prototype, "id", [tagged]);
2476
1994
  }
2477
1995
  set id(id) {
2478
1996
  const normalizedId = coerceId(id);
2479
- const identifier = recordIdentifierFor$1(this);
1997
+ const identifier = recordIdentifierFor(this);
2480
1998
  const didChange = normalizedId !== identifier.id;
2481
1999
  macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2482
2000
  if (!test) {
@@ -3698,7 +3216,7 @@ class Model extends EmberObject {
3698
3216
  if (isAttributeSchema(meta)) {
3699
3217
  macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
3700
3218
  if (!test) {
3701
- 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());
3219
+ 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());
3702
3220
  }
3703
3221
  })(name !== 'id') : {};
3704
3222
 
@@ -4374,9 +3892,9 @@ class HasManyReference {
4374
3892
  * @public
4375
3893
  */
4376
3894
  get identifiers() {
3895
+ ensureRefCanSubscribe(this);
4377
3896
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
4378
- this._ref; // consume the tracked prop
4379
-
3897
+ this._ref;
4380
3898
  const resource = this._resource();
4381
3899
  const map = this.___relatedTokenMap;
4382
3900
  this.___relatedTokenMap = new Map();
@@ -4775,10 +4293,7 @@ class HasManyReference {
4775
4293
  */
4776
4294
  value() {
4777
4295
  const support = LEGACY_SUPPORT.get(this.___identifier);
4778
- const loaded = this._isLoaded();
4779
- if (!loaded) {
4780
- // subscribe to changes
4781
- // for when we are not loaded yet
4296
+ if (!ensureRefCanSubscribe(this)) {
4782
4297
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
4783
4298
  this._ref;
4784
4299
  return null;
@@ -4898,6 +4413,26 @@ function isMaybeResource(object) {
4898
4413
  const keys = Object.keys(object).filter(k => k !== 'id' && k !== 'type' && k !== 'lid');
4899
4414
  return keys.length > 0;
4900
4415
  }
4416
+ function ensureRefCanSubscribe(rel) {
4417
+ const loaded = rel._isLoaded();
4418
+ if (!loaded) {
4419
+ // subscribe to changes
4420
+ // for when we are not loaded yet
4421
+ //
4422
+ // because the graph optimizes the case where a relationship has never been subscribed,
4423
+ // we force accessed to be true here. When we make the graph public we should create a
4424
+ // subscribe/unsubscribe API
4425
+ const edge = rel.graph.get(rel.___identifier, rel.key);
4426
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
4427
+ if (!test) {
4428
+ throw new Error(`Expected a hasMany relationship for ${rel.___identifier.type}:${rel.key}`);
4429
+ }
4430
+ })('accessed' in edge) : {};
4431
+ edge.accessed = true;
4432
+ return false;
4433
+ }
4434
+ return true;
4435
+ }
4901
4436
  function isResourceIdentiferWithRelatedLinks(value) {
4902
4437
  return Boolean(value && value.links && value.links.related);
4903
4438
  }
@@ -5477,7 +5012,7 @@ class BelongsToReference {
5477
5012
  defineSignal(BelongsToReference.prototype, '_ref', 0);
5478
5013
  const LEGACY_SUPPORT = getOrSetGlobal('LEGACY_SUPPORT', new Map());
5479
5014
  function lookupLegacySupport(record) {
5480
- const identifier = recordIdentifierFor(record);
5015
+ const identifier = recordIdentifierFor$1(record);
5481
5016
  macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5482
5017
  if (!test) {
5483
5018
  throw new Error(`Expected a record`);
@@ -5500,7 +5035,7 @@ class LegacySupport {
5500
5035
  constructor(record) {
5501
5036
  this.record = record;
5502
5037
  this.store = storeFor$1(record);
5503
- this.identifier = recordIdentifierFor(record);
5038
+ this.identifier = recordIdentifierFor$1(record);
5504
5039
  this.cache = peekCache(record);
5505
5040
  if (macroCondition(dependencySatisfies('@ember-data/graph', '*'))) {
5506
5041
  const graphFor = importSync('@ember-data/graph/-private').graphFor;
@@ -5659,6 +5194,7 @@ class LegacySupport {
5659
5194
  isPolymorphic: definition.isPolymorphic,
5660
5195
  isAsync: definition.isAsync,
5661
5196
  _inverseIsAsync: definition.inverseIsAsync,
5197
+ // @ts-expect-error Typescript doesn't have a way for us to thread the generic backwards so it infers unknown instead of T
5662
5198
  manager: this,
5663
5199
  isLoaded: !definition.isAsync,
5664
5200
  allowMutation: true
@@ -5883,14 +5419,22 @@ class LegacySupport {
5883
5419
  throw new Error(`Expected stable identifiers`);
5884
5420
  }
5885
5421
  })(!identifiers || identifiers.every(isStableIdentifier)) : {};
5886
- return this.store.request({
5422
+ const req = field.options.linksMode ? {
5423
+ url: getRelatedLink(resource),
5424
+ op: 'findHasMany',
5425
+ method: 'GET',
5426
+ records: identifiers || [],
5427
+ data: request,
5428
+ [EnableHydration]: false
5429
+ } : {
5887
5430
  op: 'findHasMany',
5888
5431
  records: identifiers || [],
5889
5432
  data: request,
5890
5433
  cacheOptions: {
5891
5434
  [Symbol.for('wd:skip-cache')]: true
5892
5435
  }
5893
- });
5436
+ };
5437
+ return this.store.request(req);
5894
5438
  }
5895
5439
  const preferLocalCache = hasReceivedData && !isEmpty;
5896
5440
  const hasLocalPartialData = hasDematerializedInverse || isEmpty && Array.isArray(identifiers) && identifiers.length > 0;
@@ -5975,15 +5519,23 @@ class LegacySupport {
5975
5519
 
5976
5520
  // fetch via link
5977
5521
  if (shouldFindViaLink) {
5978
- const future = this.store.request({
5522
+ const req = field.options.linksMode ? {
5523
+ url: getRelatedLink(resource),
5524
+ op: 'findBelongsTo',
5525
+ method: 'GET',
5526
+ records: identifier ? [identifier] : [],
5527
+ data: request,
5528
+ [EnableHydration]: false
5529
+ } : {
5979
5530
  op: 'findBelongsTo',
5980
5531
  records: identifier ? [identifier] : [],
5981
5532
  data: request,
5982
5533
  cacheOptions: {
5983
5534
  [Symbol.for('wd:skip-cache')]: true
5984
5535
  }
5985
- });
5986
- this._pending[key] = future.then(doc => doc.content).finally(() => {
5536
+ };
5537
+ const future = this.store.request(req);
5538
+ this._pending[key] = future.then(doc => field.options.linksMode ? doc.content.data : doc.content).finally(() => {
5987
5539
  this._pending[key] = undefined;
5988
5540
  });
5989
5541
  return this._pending[key];
@@ -6053,6 +5605,15 @@ class LegacySupport {
6053
5605
  this.isDestroyed = true;
6054
5606
  }
6055
5607
  }
5608
+ function getRelatedLink(resource) {
5609
+ const related = resource.links?.related;
5610
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5611
+ if (!test) {
5612
+ throw new Error(`Expected a related link`);
5613
+ }
5614
+ })(related) : {};
5615
+ return typeof related === 'object' ? related.href : related;
5616
+ }
6056
5617
  function handleCompletedRelationshipRequest(recordExt, key, relationship, value, error) {
6057
5618
  delete recordExt._relationshipPromisesCache[key];
6058
5619
  relationship.state.shouldForceReload = false;
@@ -6112,10 +5673,10 @@ function extractIdentifierFromRecord(record) {
6112
5673
  },
6113
5674
  for: 'ember-data'
6114
5675
  });
6115
- return content ? recordIdentifierFor(content) : null;
5676
+ return content ? recordIdentifierFor$1(content) : null;
6116
5677
  }
6117
5678
  }
6118
- return recordIdentifierFor(record);
5679
+ return recordIdentifierFor$1(record);
6119
5680
  }
6120
5681
  function anyUnloaded(store, relationship) {
6121
5682
  const graph = store._graph;
@@ -6162,4 +5723,4 @@ function isBelongsTo(relationship) {
6162
5723
  function isPromiseRecord(record) {
6163
5724
  return typeof record === 'object' && !!record && 'then' in record;
6164
5725
  }
6165
- 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 };
5726
+ 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 };