@ember-data/model 5.3.10 → 5.3.12

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 (62) 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-B7JDN69X.js → has-many-DZX7l2bT.js} +1 -1
  6. package/dist/has-many-DZX7l2bT.js.map +1 -0
  7. package/dist/{hooks-CW9adWmR.js → hooks-RqMlE4Jk.js} +2 -2
  8. package/dist/{hooks-CW9adWmR.js.map → hooks-RqMlE4Jk.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 +2 -2
  13. package/dist/migration-support.js.map +1 -1
  14. package/dist/{model-CAqu4cYw.js → model-6Exz3e1N.js} +108 -520
  15. package/dist/model-6Exz3e1N.js.map +1 -0
  16. package/dist/{schema-provider-BtvdNYTK.js → schema-provider-B-FIifVG.js} +1 -1
  17. package/dist/schema-provider-B-FIifVG.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 +32 -63
  31. package/unstable-preview-types/-private/belongs-to.d.ts +1 -0
  32. package/unstable-preview-types/-private/belongs-to.d.ts.map +1 -1
  33. package/unstable-preview-types/-private/debug/assert-polymorphic-type.d.ts.map +1 -1
  34. package/unstable-preview-types/-private/legacy-relationships-support.d.ts +1 -1
  35. package/unstable-preview-types/-private/legacy-relationships-support.d.ts.map +1 -1
  36. package/unstable-preview-types/-private/model.d.ts +21 -23
  37. package/unstable-preview-types/-private/model.d.ts.map +1 -1
  38. package/unstable-preview-types/-private/notify-changes.d.ts.map +1 -1
  39. package/unstable-preview-types/-private/promise-many-array.d.ts +1 -1
  40. package/unstable-preview-types/-private/promise-many-array.d.ts.map +1 -1
  41. package/unstable-preview-types/-private/promise-proxy-base.d.ts +5 -0
  42. package/unstable-preview-types/-private/promise-proxy-base.d.ts.map +1 -0
  43. package/unstable-preview-types/-private/record-state.d.ts +1 -1
  44. package/unstable-preview-types/-private/references/has-many.d.ts +1 -1
  45. package/unstable-preview-types/-private/references/has-many.d.ts.map +1 -1
  46. package/unstable-preview-types/-private/schema-provider.d.ts +7 -7
  47. package/unstable-preview-types/-private/schema-provider.d.ts.map +1 -1
  48. package/unstable-preview-types/-private/type-utils.d.ts +1 -1
  49. package/unstable-preview-types/-private/type-utils.d.ts.map +1 -1
  50. package/unstable-preview-types/-private.d.ts +1 -1
  51. package/unstable-preview-types/-private.d.ts.map +1 -1
  52. package/unstable-preview-types/index.d.ts +19 -19
  53. package/unstable-preview-types/index.d.ts.map +1 -1
  54. package/unstable-preview-types/migration-support.d.ts +11 -4
  55. package/unstable-preview-types/migration-support.d.ts.map +1 -1
  56. package/dist/has-many-B7JDN69X.js.map +0 -1
  57. package/dist/model-CAqu4cYw.js.map +0 -1
  58. package/dist/schema-provider-BtvdNYTK.js.map +0 -1
  59. package/unstable-preview-types/-private/many-array.d.ts +0 -196
  60. package/unstable-preview-types/-private/many-array.d.ts.map +0 -1
  61. /package/{ember-data-logo-dark.svg → logos/ember-data-logo-dark.svg} +0 -0
  62. /package/{ember-data-logo-light.svg → logos/ember-data-logo-light.svg} +0 -0
@@ -3,15 +3,16 @@ 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';
6
+ import { isStableIdentifier, recordIdentifierFor, storeFor, peekCache, SOURCE, fastPush, RelatedCollection, coerceId } from '@ember-data/store/-private';
7
7
  import { cached, compat } from '@ember-data/tracking';
8
- import { addToTransaction, defineSignal, peekSignal, getSignal, subscribe } from '@ember-data/tracking/-private';
8
+ import { defineSignal, peekSignal, addToTransaction, getSignal, subscribe } 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';
12
12
  import { mapBy, not } from '@ember/object/computed';
13
13
  import { upgradeStore } from '@ember-data/legacy-compat/-private';
14
14
  import { getOrSetGlobal } from '@warp-drive/core-types/-private';
15
+ import { EnableHydration } from '@warp-drive/core-types/request';
15
16
  import PromiseProxyMixin from '@ember/object/promise-proxy-mixin';
16
17
  import ObjectProxy from '@ember/object/proxy';
17
18
  import { cacheFor } from '@ember/object/internals';
@@ -46,466 +47,6 @@ function normalizeModelName(type) {
46
47
  }
47
48
  return type;
48
49
  }
49
-
50
- /**
51
- @module @ember-data/store
52
- */
53
- /**
54
- A `ManyArray` is a `MutableArray` that represents the contents of a has-many
55
- relationship.
56
-
57
- The `ManyArray` is instantiated lazily the first time the relationship is
58
- requested.
59
-
60
- This class is not intended to be directly instantiated by consuming applications.
61
-
62
- ### Inverses
63
-
64
- Often, the relationships in Ember Data applications will have
65
- an inverse. For example, imagine the following models are
66
- defined:
67
-
68
- ```app/models/post.js
69
- import Model, { hasMany } from '@ember-data/model';
70
-
71
- export default class PostModel extends Model {
72
- @hasMany('comment') comments;
73
- }
74
- ```
75
-
76
- ```app/models/comment.js
77
- import Model, { belongsTo } from '@ember-data/model';
78
-
79
- export default class CommentModel extends Model {
80
- @belongsTo('post') post;
81
- }
82
- ```
83
-
84
- If you created a new instance of `Post` and added
85
- a `Comment` record to its `comments` has-many
86
- relationship, you would expect the comment's `post`
87
- property to be set to the post that contained
88
- the has-many.
89
-
90
- We call the record to which a relationship belongs-to the
91
- relationship's _owner_.
92
-
93
- @class ManyArray
94
- @public
95
- */
96
- class RelatedCollection extends LiveArray {
97
- /**
98
- The loading state of this array
99
- @property {Boolean} isLoaded
100
- @public
101
- */
102
-
103
- /**
104
- `true` if the relationship is polymorphic, `false` otherwise.
105
- @property {Boolean} isPolymorphic
106
- @private
107
- */
108
-
109
- /**
110
- Metadata associated with the request for async hasMany relationships.
111
- Example
112
- Given that the server returns the following JSON payload when fetching a
113
- hasMany relationship:
114
- ```js
115
- {
116
- "comments": [{
117
- "id": 1,
118
- "comment": "This is the first comment",
119
- }, {
120
- // ...
121
- }],
122
- "meta": {
123
- "page": 1,
124
- "total": 5
125
- }
126
- }
127
- ```
128
- You can then access the meta data via the `meta` property:
129
- ```js
130
- let comments = await post.comments;
131
- let meta = comments.meta;
132
- // meta.page => 1
133
- // meta.total => 5
134
- ```
135
- @property {Object | null} meta
136
- @public
137
- */
138
-
139
- /**
140
- * Retrieve the links for this relationship
141
- *
142
- @property {Object | null} links
143
- @public
144
- */
145
-
146
- constructor(options) {
147
- super(options);
148
- this.isLoaded = options.isLoaded || false;
149
- this.isAsync = options.isAsync || false;
150
- this.isPolymorphic = options.isPolymorphic || false;
151
- this.identifier = options.identifier;
152
- this.key = options.key;
153
- }
154
- [MUTATE](target, receiver, prop, args, _SIGNAL) {
155
- switch (prop) {
156
- case 'length 0':
157
- {
158
- Reflect.set(target, 'length', 0);
159
- mutateReplaceRelatedRecords(this, [], _SIGNAL);
160
- return true;
161
- }
162
- case 'replace cell':
163
- {
164
- const [index, prior, value] = args;
165
- target[index] = value;
166
- mutateReplaceRelatedRecord(this, {
167
- value,
168
- prior,
169
- index
170
- }, _SIGNAL);
171
- return true;
172
- }
173
- case 'push':
174
- {
175
- const newValues = extractIdentifiersFromRecords(args);
176
- assertNoDuplicates(this, target, currentState => currentState.push(...newValues), `Cannot push duplicates to a hasMany's state.`);
177
- if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
178
- // dedupe
179
- const seen = new Set(target);
180
- const unique = new Set();
181
- args.forEach(item => {
182
- const identifier = recordIdentifierFor(item);
183
- if (!seen.has(identifier)) {
184
- seen.add(identifier);
185
- unique.add(item);
186
- }
187
- });
188
- const newArgs = Array.from(unique);
189
- const result = Reflect.apply(target[prop], receiver, newArgs);
190
- if (newArgs.length) {
191
- mutateAddToRelatedRecords(this, {
192
- value: extractIdentifiersFromRecords(newArgs)
193
- }, _SIGNAL);
194
- }
195
- return result;
196
- }
197
-
198
- // else, no dedupe, error on duplicates
199
- const result = Reflect.apply(target[prop], receiver, args);
200
- if (newValues.length) {
201
- mutateAddToRelatedRecords(this, {
202
- value: newValues
203
- }, _SIGNAL);
204
- }
205
- return result;
206
- }
207
- case 'pop':
208
- {
209
- const result = Reflect.apply(target[prop], receiver, args);
210
- if (result) {
211
- mutateRemoveFromRelatedRecords(this, {
212
- value: recordIdentifierFor(result)
213
- }, _SIGNAL);
214
- }
215
- return result;
216
- }
217
- case 'unshift':
218
- {
219
- const newValues = extractIdentifiersFromRecords(args);
220
- assertNoDuplicates(this, target, currentState => currentState.unshift(...newValues), `Cannot unshift duplicates to a hasMany's state.`);
221
- if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
222
- // dedupe
223
- const seen = new Set(target);
224
- const unique = new Set();
225
- args.forEach(item => {
226
- const identifier = recordIdentifierFor(item);
227
- if (!seen.has(identifier)) {
228
- seen.add(identifier);
229
- unique.add(item);
230
- }
231
- });
232
- const newArgs = Array.from(unique);
233
- const result = Reflect.apply(target[prop], receiver, newArgs);
234
- if (newArgs.length) {
235
- mutateAddToRelatedRecords(this, {
236
- value: extractIdentifiersFromRecords(newArgs),
237
- index: 0
238
- }, _SIGNAL);
239
- }
240
- return result;
241
- }
242
-
243
- // else, no dedupe, error on duplicates
244
- const result = Reflect.apply(target[prop], receiver, args);
245
- if (newValues.length) {
246
- mutateAddToRelatedRecords(this, {
247
- value: newValues,
248
- index: 0
249
- }, _SIGNAL);
250
- }
251
- return result;
252
- }
253
- case 'shift':
254
- {
255
- const result = Reflect.apply(target[prop], receiver, args);
256
- if (result) {
257
- mutateRemoveFromRelatedRecords(this, {
258
- value: recordIdentifierFor(result),
259
- index: 0
260
- }, _SIGNAL);
261
- }
262
- return result;
263
- }
264
- case 'sort':
265
- {
266
- const result = Reflect.apply(target[prop], receiver, args);
267
- mutateSortRelatedRecords(this, result.map(recordIdentifierFor), _SIGNAL);
268
- return result;
269
- }
270
- case 'splice':
271
- {
272
- const [start, deleteCount, ...adds] = args;
273
-
274
- // detect a full replace
275
- if (start === 0 && deleteCount === this[SOURCE].length) {
276
- const newValues = extractIdentifiersFromRecords(adds);
277
- assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot replace a hasMany's state with a new state that contains duplicates.`);
278
- if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
279
- // dedupe
280
- const current = new Set(adds);
281
- const unique = Array.from(current);
282
- const newArgs = [start, deleteCount].concat(unique);
283
- const result = Reflect.apply(target[prop], receiver, newArgs);
284
- mutateReplaceRelatedRecords(this, extractIdentifiersFromRecords(unique), _SIGNAL);
285
- return result;
286
- }
287
-
288
- // else, no dedupe, error on duplicates
289
- const result = Reflect.apply(target[prop], receiver, args);
290
- mutateReplaceRelatedRecords(this, newValues, _SIGNAL);
291
- return result;
292
- }
293
- const newValues = extractIdentifiersFromRecords(adds);
294
- assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot splice a hasMany's state with a new state that contains duplicates.`);
295
- if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
296
- // dedupe
297
- const currentState = target.slice();
298
- currentState.splice(start, deleteCount);
299
- const seen = new Set(currentState);
300
- const unique = [];
301
- adds.forEach(item => {
302
- const identifier = recordIdentifierFor(item);
303
- if (!seen.has(identifier)) {
304
- seen.add(identifier);
305
- unique.push(item);
306
- }
307
- });
308
- const newArgs = [start, deleteCount, ...unique];
309
- const result = Reflect.apply(target[prop], receiver, newArgs);
310
- if (deleteCount > 0) {
311
- mutateRemoveFromRelatedRecords(this, {
312
- value: result.map(recordIdentifierFor),
313
- index: start
314
- }, _SIGNAL);
315
- }
316
- if (unique.length > 0) {
317
- mutateAddToRelatedRecords(this, {
318
- value: extractIdentifiersFromRecords(unique),
319
- index: start
320
- }, _SIGNAL);
321
- }
322
- return result;
323
- }
324
-
325
- // else, no dedupe, error on duplicates
326
- const result = Reflect.apply(target[prop], receiver, args);
327
- if (deleteCount > 0) {
328
- mutateRemoveFromRelatedRecords(this, {
329
- value: result.map(recordIdentifierFor),
330
- index: start
331
- }, _SIGNAL);
332
- }
333
- if (newValues.length > 0) {
334
- mutateAddToRelatedRecords(this, {
335
- value: newValues,
336
- index: start
337
- }, _SIGNAL);
338
- }
339
- return result;
340
- }
341
- default:
342
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
343
- {
344
- throw new Error(`unable to convert ${prop} into a transaction that updates the cache state for this record array`);
345
- }
346
- })() : {};
347
- }
348
- }
349
- notify() {
350
- const signal = this[ARRAY_SIGNAL];
351
- signal.shouldReset = true;
352
- notifyArray(this);
353
- }
354
-
355
- /**
356
- Reloads all of the records in the manyArray. If the manyArray
357
- holds a relationship that was originally fetched using a links url
358
- EmberData will revisit the original links url to repopulate the
359
- relationship.
360
- If the ManyArray holds the result of a `store.query()` reload will
361
- re-run the original query.
362
- Example
363
- ```javascript
364
- let user = store.peekRecord('user', '1')
365
- await login(user);
366
- let permissions = await user.permissions;
367
- await permissions.reload();
368
- ```
369
- @method reload
370
- @public
371
- */
372
- reload(options) {
373
- // TODO this is odd, we don't ask the store for anything else like this?
374
- return this._manager.reloadHasMany(this.key, options);
375
- }
376
-
377
- /**
378
- Saves all of the records in the `ManyArray`.
379
- Example
380
- ```javascript
381
- let inbox = await store.findRecord('inbox', '1');
382
- let messages = await inbox.messages;
383
- messages.forEach((message) => {
384
- message.isRead = true;
385
- });
386
- messages.save();
387
- ```
388
- @method save
389
- @public
390
- @return {PromiseArray} promise
391
- */
392
-
393
- /**
394
- Create a child record within the owner
395
- @method createRecord
396
- @public
397
- @param {Object} hash
398
- @return {Model} record
399
- */
400
- createRecord(hash) {
401
- const {
402
- store
403
- } = this;
404
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
405
- if (!test) {
406
- throw new Error(`Expected modelName to be set`);
407
- }
408
- })(this.modelName) : {};
409
- const record = store.createRecord(this.modelName, hash);
410
- this.push(record);
411
- return record;
412
- }
413
- destroy() {
414
- super.destroy(false);
415
- }
416
- }
417
- RelatedCollection.prototype.isAsync = false;
418
- RelatedCollection.prototype.isPolymorphic = false;
419
- RelatedCollection.prototype.identifier = null;
420
- RelatedCollection.prototype.cache = null;
421
- RelatedCollection.prototype._inverseIsAsync = false;
422
- RelatedCollection.prototype.key = '';
423
- RelatedCollection.prototype.DEPRECATED_CLASS_NAME = 'ManyArray';
424
- function assertRecordPassedToHasMany(record) {
425
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
426
- if (!test) {
427
- throw new Error(`All elements of a hasMany relationship must be instances of Model, you passed ${typeof record}`);
428
- }
429
- })(function () {
430
- try {
431
- recordIdentifierFor(record);
432
- return true;
433
- } catch {
434
- return false;
435
- }
436
- }()) : {};
437
- }
438
- function extractIdentifiersFromRecords(records) {
439
- return records.map(extractIdentifierFromRecord$1);
440
- }
441
- function extractIdentifierFromRecord$1(recordOrPromiseRecord) {
442
- assertRecordPassedToHasMany(recordOrPromiseRecord);
443
- return recordIdentifierFor(recordOrPromiseRecord);
444
- }
445
- function assertNoDuplicates(collection, target, callback, reason) {
446
- const state = target.slice();
447
- callback(state);
448
- if (state.length !== new Set(state).size) {
449
- const duplicates = state.filter((currentValue, currentIndex) => state.indexOf(currentValue) !== currentIndex);
450
- if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
451
- 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, {
452
- id: 'ember-data:deprecate-many-array-duplicates',
453
- for: 'ember-data',
454
- until: '6.0',
455
- since: {
456
- enabled: '5.3',
457
- available: '4.13'
458
- }
459
- });
460
- } else {
461
- 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- ')}`);
462
- }
463
- }
464
- }
465
- function mutateAddToRelatedRecords(collection, operationInfo, _SIGNAL) {
466
- mutate(collection, {
467
- op: 'addToRelatedRecords',
468
- record: collection.identifier,
469
- field: collection.key,
470
- ...operationInfo
471
- }, _SIGNAL);
472
- }
473
- function mutateRemoveFromRelatedRecords(collection, operationInfo, _SIGNAL) {
474
- mutate(collection, {
475
- op: 'removeFromRelatedRecords',
476
- record: collection.identifier,
477
- field: collection.key,
478
- ...operationInfo
479
- }, _SIGNAL);
480
- }
481
- function mutateReplaceRelatedRecord(collection, operationInfo, _SIGNAL) {
482
- mutate(collection, {
483
- op: 'replaceRelatedRecord',
484
- record: collection.identifier,
485
- field: collection.key,
486
- ...operationInfo
487
- }, _SIGNAL);
488
- }
489
- function mutateReplaceRelatedRecords(collection, value, _SIGNAL) {
490
- mutate(collection, {
491
- op: 'replaceRelatedRecords',
492
- record: collection.identifier,
493
- field: collection.key,
494
- value
495
- }, _SIGNAL);
496
- }
497
- function mutateSortRelatedRecords(collection, value, _SIGNAL) {
498
- mutate(collection, {
499
- op: 'sortRelatedRecords',
500
- record: collection.identifier,
501
- field: collection.key,
502
- value
503
- }, _SIGNAL);
504
- }
505
- function mutate(collection, mutation, _SIGNAL) {
506
- collection._manager.mutate(mutation);
507
- addToTransaction(_SIGNAL);
508
- }
509
50
  const PromiseObject = ObjectProxy.extend(PromiseProxyMixin);
510
51
  const deferred = /* @__PURE__ */new WeakMap();
511
52
  function deferDecorator(proto, prop, desc) {
@@ -895,16 +436,18 @@ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
895
436
  }
896
437
  if (parentDefinition.isPolymorphic) {
897
438
  const meta = store.schema.fields(addedIdentifier)?.get(parentDefinition.inverseKey);
898
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
899
- if (!test) {
900
- throw new Error(`Expected the schema for the field ${parentDefinition.inverseKey} on ${addedIdentifier.type} to be for a legacy relationship`);
901
- }
902
- })(!meta || meta.kind === 'belongsTo' || meta.kind === 'hasMany') : {};
903
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
904
- if (!test) {
905
- 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.`);
906
- }
907
- })(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
+ }
908
451
  }
909
452
  };
910
453
  }
@@ -994,9 +537,9 @@ class HasManyReference {
994
537
  * @public
995
538
  */
996
539
  get identifiers() {
540
+ ensureRefCanSubscribe(this);
997
541
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
998
- this._ref; // consume the tracked prop
999
-
542
+ this._ref;
1000
543
  const resource = this._resource();
1001
544
  const map = this.___relatedTokenMap;
1002
545
  this.___relatedTokenMap = new Map();
@@ -1378,10 +921,7 @@ class HasManyReference {
1378
921
  */
1379
922
  value() {
1380
923
  const support = LEGACY_SUPPORT.get(this.___identifier);
1381
- const loaded = this._isLoaded();
1382
- if (!loaded) {
1383
- // subscribe to changes
1384
- // for when we are not loaded yet
924
+ if (!ensureRefCanSubscribe(this)) {
1385
925
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
1386
926
  this._ref;
1387
927
  return null;
@@ -1501,6 +1041,26 @@ function isMaybeResource(object) {
1501
1041
  const keys = Object.keys(object).filter(k => k !== 'id' && k !== 'type' && k !== 'lid');
1502
1042
  return keys.length > 0;
1503
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
+ }
1504
1064
  function isResourceIdentiferWithRelatedLinks(value) {
1505
1065
  return Boolean(value && value.links && value.links.related);
1506
1066
  }
@@ -2245,6 +1805,7 @@ class LegacySupport {
2245
1805
  isPolymorphic: definition.isPolymorphic,
2246
1806
  isAsync: definition.isAsync,
2247
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
2248
1809
  manager: this,
2249
1810
  isLoaded: !definition.isAsync,
2250
1811
  allowMutation: true
@@ -2469,14 +2030,22 @@ class LegacySupport {
2469
2030
  throw new Error(`Expected stable identifiers`);
2470
2031
  }
2471
2032
  })(!identifiers || identifiers.every(isStableIdentifier)) : {};
2472
- return this.store.request({
2033
+ const req = field.options.linksMode ? {
2034
+ url: getRelatedLink(resource),
2035
+ op: 'findHasMany',
2036
+ method: 'GET',
2037
+ records: identifiers || [],
2038
+ data: request,
2039
+ [EnableHydration]: false
2040
+ } : {
2473
2041
  op: 'findHasMany',
2474
2042
  records: identifiers || [],
2475
2043
  data: request,
2476
2044
  cacheOptions: {
2477
2045
  [Symbol.for('wd:skip-cache')]: true
2478
2046
  }
2479
- });
2047
+ };
2048
+ return this.store.request(req);
2480
2049
  }
2481
2050
  const preferLocalCache = hasReceivedData && !isEmpty;
2482
2051
  const hasLocalPartialData = hasDematerializedInverse || isEmpty && Array.isArray(identifiers) && identifiers.length > 0;
@@ -2561,15 +2130,23 @@ class LegacySupport {
2561
2130
 
2562
2131
  // fetch via link
2563
2132
  if (shouldFindViaLink) {
2564
- const future = this.store.request({
2133
+ const req = field.options.linksMode ? {
2134
+ url: getRelatedLink(resource),
2135
+ op: 'findBelongsTo',
2136
+ method: 'GET',
2137
+ records: identifier ? [identifier] : [],
2138
+ data: request,
2139
+ [EnableHydration]: false
2140
+ } : {
2565
2141
  op: 'findBelongsTo',
2566
2142
  records: identifier ? [identifier] : [],
2567
2143
  data: request,
2568
2144
  cacheOptions: {
2569
2145
  [Symbol.for('wd:skip-cache')]: true
2570
2146
  }
2571
- });
2572
- this._pending[key] = future.then(doc => doc.content).finally(() => {
2147
+ };
2148
+ const future = this.store.request(req);
2149
+ this._pending[key] = future.then(doc => field.options.linksMode ? doc.content.data : doc.content).finally(() => {
2573
2150
  this._pending[key] = undefined;
2574
2151
  });
2575
2152
  return this._pending[key];
@@ -2639,6 +2216,15 @@ class LegacySupport {
2639
2216
  this.isDestroyed = true;
2640
2217
  }
2641
2218
  }
2219
+ function getRelatedLink(resource) {
2220
+ const related = resource.links?.related;
2221
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2222
+ if (!test) {
2223
+ throw new Error(`Expected a related link`);
2224
+ }
2225
+ })(related) : {};
2226
+ return typeof related === 'object' ? related.href : related;
2227
+ }
2642
2228
  function handleCompletedRelationshipRequest(recordExt, key, relationship, value, error) {
2643
2229
  delete recordExt._relationshipPromisesCache[key];
2644
2230
  relationship.state.shouldForceReload = false;
@@ -3190,30 +2776,35 @@ function createSnapshot() {
3190
2776
  return store._fetchManager.createSnapshot(recordIdentifierFor$1(this));
3191
2777
  }
3192
2778
  function notifyChanges(identifier, value, key, record, store) {
3193
- if (value === 'attributes') {
3194
- if (key) {
3195
- notifyAttribute(store, identifier, key, record);
3196
- } else {
3197
- record.eachAttribute(name => {
3198
- notifyAttribute(store, identifier, name, record);
3199
- });
3200
- }
3201
- } else if (value === 'relationships') {
3202
- if (key) {
3203
- const meta = record.constructor.relationshipsByName.get(key);
3204
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
3205
- if (!test) {
3206
- throw new Error(`Expected to find a relationship for ${key} on ${identifier.type}`);
3207
- }
3208
- })(meta) : {};
3209
- notifyRelationship(identifier, key, record, meta);
3210
- } else {
3211
- record.eachRelationship((name, meta) => {
3212
- notifyRelationship(identifier, name, record, meta);
3213
- });
3214
- }
3215
- } else if (value === 'identity') {
3216
- 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;
3217
2808
  }
3218
2809
  }
3219
2810
  function notifyRelationship(identifier, key, record, meta) {
@@ -3812,9 +3403,8 @@ class Model extends EmberObject {
3812
3403
  ```javascript
3813
3404
  let record = store.createRecord('model');
3814
3405
  record.isLoaded; // true
3815
- store.findRecord('model', 1).then(function(model) {
3816
- model.isLoaded; // true
3817
- });
3406
+ const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' }));
3407
+ model.isLoaded;
3818
3408
  ```
3819
3409
  @property isLoaded
3820
3410
  @public
@@ -3837,11 +3427,10 @@ class Model extends EmberObject {
3837
3427
  ```javascript
3838
3428
  let record = store.createRecord('model');
3839
3429
  record.hasDirtyAttributes; // true
3840
- store.findRecord('model', 1).then(function(model) {
3841
- model.hasDirtyAttributes; // false
3842
- model.set('foo', 'some value');
3843
- model.hasDirtyAttributes; // true
3844
- });
3430
+ const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' }));
3431
+ model.hasDirtyAttributes; // false
3432
+ model.foo = 'some value';
3433
+ model.hasDirtyAttributes; // true
3845
3434
  ```
3846
3435
  @since 1.13.0
3847
3436
  @property hasDirtyAttributes
@@ -4042,9 +3631,8 @@ class Model extends EmberObject {
4042
3631
  ```javascript
4043
3632
  let record = store.createRecord('model');
4044
3633
  record.id; // null
4045
- store.findRecord('model', 1).then(function(model) {
4046
- model.id; // '1'
4047
- });
3634
+ const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' }));
3635
+ model.id; // '1'
4048
3636
  ```
4049
3637
  @property id
4050
3638
  @public
@@ -5117,7 +4705,7 @@ class Model extends EmberObject {
5117
4705
  if (isAttributeSchema(meta)) {
5118
4706
  macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
5119
4707
  if (!test) {
5120
- 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());
4708
+ 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());
5121
4709
  }
5122
4710
  })(name !== 'id') : {};
5123
4711
 
@@ -5352,4 +4940,4 @@ function isRelationshipSchema(meta) {
5352
4940
  function isAttributeSchema(meta) {
5353
4941
  return typeof meta === 'object' && meta !== null && 'kind' in meta && meta.kind === 'attribute';
5354
4942
  }
5355
- 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 };
4943
+ 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 };