@warp-drive/legacy 5.9.0-beta.0 → 5.9.0-beta.1

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 (162) hide show
  1. package/README.md +6 -0
  2. package/declarations/adapter/-private/build-url-mixin.d.ts +156 -0
  3. package/declarations/adapter/error.d.ts +385 -169
  4. package/declarations/adapter/json-api.d.ts +12 -1
  5. package/declarations/adapter/rest.d.ts +74 -0
  6. package/declarations/adapter.d.ts +6 -0
  7. package/declarations/compat/builders/find-all.d.ts +0 -1
  8. package/declarations/compat/extensions.d.ts +40 -0
  9. package/declarations/compat/legacy-network-handler/legacy-network-handler.d.ts +7 -0
  10. package/declarations/compat/legacy-network-handler/minimum-adapter-interface.d.ts +4 -0
  11. package/declarations/compat/legacy-network-handler/minimum-serializer-interface.d.ts +7 -0
  12. package/declarations/compat/utils.d.ts +11 -0
  13. package/declarations/compat.d.ts +32 -0
  14. package/declarations/index.d.ts +142 -0
  15. package/declarations/model/-private/attr.d.ts +21 -0
  16. package/declarations/model/-private/belongs-to.d.ts +21 -0
  17. package/declarations/model/-private/hooks.d.ts +26 -0
  18. package/declarations/model/-private/model.d.ts +55 -4
  19. package/declarations/model/-private/promise-many-array.d.ts +25 -1
  20. package/declarations/model/-private/schema-provider.d.ts +11 -1
  21. package/declarations/model/migration-support.d.ts +31 -5
  22. package/declarations/model-fragments/extensions/fragment-array.d.ts +38 -0
  23. package/declarations/model-fragments/extensions/fragment.d.ts +35 -0
  24. package/declarations/model-fragments/hooks/model-for.d.ts +7 -0
  25. package/declarations/model-fragments/index.d.ts +8 -0
  26. package/declarations/model-fragments/instance-initializers/fragment-extensions.d.ts +6 -0
  27. package/declarations/model-fragments/utilities/with-array-defaults.d.ts +43 -2
  28. package/declarations/model-fragments/utilities/with-fragment-array-defaults.d.ts +18 -0
  29. package/declarations/model-fragments/utilities/with-fragment-defaults.d.ts +15 -0
  30. package/declarations/model-fragments/utilities/with-legacy.d.ts +8 -0
  31. package/declarations/serializer/-private/transforms/boolean.d.ts +13 -0
  32. package/declarations/serializer/-private/transforms/date.d.ts +15 -1
  33. package/declarations/serializer/-private/transforms/number.d.ts +14 -1
  34. package/declarations/serializer/-private/transforms/string.d.ts +14 -1
  35. package/declarations/serializer/-private/utils.d.ts +24 -0
  36. package/declarations/serializer/json-api.d.ts +1 -1
  37. package/declarations/serializer.d.ts +4 -6
  38. package/declarations/store/-private.d.ts +2 -2
  39. package/declarations/store.d.ts +7 -0
  40. package/dist/adapter/error.js +386 -241
  41. package/dist/adapter/json-api.js +12 -0
  42. package/dist/adapter/rest.js +39 -3
  43. package/dist/adapter.js +23 -26
  44. package/dist/compat/builders.js +0 -1
  45. package/dist/compat/extensions.js +80 -3
  46. package/dist/compat/utils.js +14 -0
  47. package/dist/compat.js +17 -0
  48. package/dist/{errors-Cz5KrzBk.js → errors-DZKA206g.js} +24 -1
  49. package/dist/{hooks-D6diaM34.js → hooks-BvOqJBei.js} +33 -2
  50. package/dist/index.js +168 -13
  51. package/dist/{json-ChdEfB0X.js → json-DU8m1pGf.js} +83 -6
  52. package/dist/model/-private.js +1 -1
  53. package/dist/model/migration-support.js +15 -2
  54. package/dist/{unpkg/dev-deprecated/model-for-CqXsIKws.js → model-for-CXkJw59V.js} +77 -1
  55. package/dist/model-fragments.js +24 -5
  56. package/dist/model.js +12 -8
  57. package/dist/{schema-provider-DJCV_6AF.js → schema-provider-DtPOp0d7.js} +93 -6
  58. package/dist/serializer/json-api.js +8 -3
  59. package/dist/serializer/json.js +1 -1
  60. package/dist/serializer/rest.js +3 -4
  61. package/dist/serializer/transform.js +51 -3
  62. package/dist/serializer.js +4 -7
  63. package/dist/store.js +13 -7
  64. package/dist/unpkg/dev/adapter/error.js +386 -241
  65. package/dist/unpkg/dev/adapter/json-api.js +13 -1
  66. package/dist/unpkg/dev/adapter/rest.js +39 -3
  67. package/dist/unpkg/dev/adapter.js +23 -26
  68. package/dist/unpkg/dev/compat/builders.js +0 -1
  69. package/dist/unpkg/dev/compat/extensions.js +80 -3
  70. package/dist/unpkg/dev/compat/utils.js +14 -0
  71. package/dist/unpkg/dev/compat.js +34 -1
  72. package/dist/unpkg/dev/{errors-DmGGJr3T.js → errors-DngRU-If.js} +24 -1
  73. package/dist/unpkg/dev/{hooks-CkYiE6Ud.js → hooks-UuiLxWxS.js} +33 -2
  74. package/dist/unpkg/dev/index.js +171 -13
  75. package/dist/unpkg/dev/json-K2Y9z6MN.js +1333 -0
  76. package/dist/unpkg/dev/model/-private.js +1 -1
  77. package/dist/unpkg/dev/model/migration-support.js +16 -2
  78. package/dist/unpkg/{prod-deprecated/model-for-CqXsIKws.js → dev/model-for-CXkJw59V.js} +77 -1
  79. package/dist/unpkg/dev/model-fragments.js +24 -5
  80. package/dist/unpkg/dev/model.js +12 -8
  81. package/dist/unpkg/dev/{schema-provider-DDVYxmUV.js → schema-provider-0D7f-QOn.js} +92 -6
  82. package/dist/unpkg/dev/serializer/json-api.js +9 -4
  83. package/dist/unpkg/dev/serializer/json.js +1 -1
  84. package/dist/unpkg/dev/serializer/rest.js +3 -4
  85. package/dist/unpkg/dev/serializer/transform.js +51 -3
  86. package/dist/unpkg/dev/serializer.js +4 -7
  87. package/dist/unpkg/dev/store.js +21 -7
  88. package/dist/unpkg/dev-deprecated/adapter/error.js +386 -241
  89. package/dist/unpkg/dev-deprecated/adapter/json-api.js +13 -1
  90. package/dist/unpkg/dev-deprecated/adapter/rest.js +39 -3
  91. package/dist/unpkg/dev-deprecated/adapter.js +23 -26
  92. package/dist/unpkg/dev-deprecated/compat/builders.js +0 -1
  93. package/dist/unpkg/dev-deprecated/compat/extensions.js +80 -3
  94. package/dist/unpkg/dev-deprecated/compat/utils.js +14 -0
  95. package/dist/unpkg/dev-deprecated/compat.js +34 -1
  96. package/dist/unpkg/dev-deprecated/{errors-Spt6ubMd.js → errors-Bzidntpi.js} +24 -1
  97. package/dist/unpkg/dev-deprecated/{hooks-DOXegvhL.js → hooks-DVXhMW14.js} +33 -2
  98. package/dist/unpkg/dev-deprecated/index.js +171 -13
  99. package/dist/unpkg/{prod-deprecated/json-BWrZ5546.js → dev-deprecated/json-K2Y9z6MN.js} +96 -6
  100. package/dist/unpkg/dev-deprecated/model/-private.js +1 -1
  101. package/dist/unpkg/dev-deprecated/model/migration-support.js +16 -2
  102. package/dist/unpkg/{dev/model-for-CqXsIKws.js → dev-deprecated/model-for-CXkJw59V.js} +77 -1
  103. package/dist/unpkg/dev-deprecated/model-fragments.js +24 -5
  104. package/dist/unpkg/dev-deprecated/model.js +12 -8
  105. package/dist/unpkg/dev-deprecated/{schema-provider-BP6_8N-V.js → schema-provider-ZwO5_fZw.js} +84 -3
  106. package/dist/unpkg/dev-deprecated/serializer/json-api.js +9 -4
  107. package/dist/unpkg/dev-deprecated/serializer/json.js +1 -1
  108. package/dist/unpkg/dev-deprecated/serializer/rest.js +3 -4
  109. package/dist/unpkg/dev-deprecated/serializer/transform.js +51 -3
  110. package/dist/unpkg/dev-deprecated/serializer.js +4 -7
  111. package/dist/unpkg/dev-deprecated/store.js +21 -7
  112. package/dist/unpkg/prod/adapter/error.js +386 -241
  113. package/dist/unpkg/prod/adapter/json-api.js +13 -1
  114. package/dist/unpkg/prod/adapter/rest.js +39 -3
  115. package/dist/unpkg/prod/adapter.js +23 -26
  116. package/dist/unpkg/prod/compat/builders.js +0 -1
  117. package/dist/unpkg/prod/compat/extensions.js +70 -3
  118. package/dist/unpkg/prod/compat/utils.js +14 -0
  119. package/dist/unpkg/prod/compat.js +17 -0
  120. package/dist/unpkg/prod/{errors-BGVFCBmi.js → errors-B-PWeYlW.js} +24 -1
  121. package/dist/unpkg/prod/{hooks-BztVA_x0.js → hooks-Bx-zBziU.js} +32 -1
  122. package/dist/unpkg/prod/index.js +171 -5
  123. package/dist/unpkg/{dev/json-Cu1LNgmQ.js → prod/json-Qewu-UN9.js} +63 -19
  124. package/dist/unpkg/prod/model/-private.js +1 -1
  125. package/dist/unpkg/prod/model/migration-support.js +16 -2
  126. package/dist/unpkg/prod/model-for-CXkJw59V.js +297 -0
  127. package/dist/unpkg/prod/model-fragments.js +24 -5
  128. package/dist/unpkg/prod/model.js +12 -8
  129. package/dist/unpkg/prod/{schema-provider-DJtD_8jZ.js → schema-provider-BgRqk8i9.js} +96 -6
  130. package/dist/unpkg/prod/serializer/json-api.js +9 -4
  131. package/dist/unpkg/prod/serializer/json.js +1 -1
  132. package/dist/unpkg/prod/serializer/rest.js +3 -4
  133. package/dist/unpkg/prod/serializer/transform.js +51 -3
  134. package/dist/unpkg/prod/serializer.js +4 -7
  135. package/dist/unpkg/prod/store.js +21 -7
  136. package/dist/unpkg/prod-deprecated/adapter/error.js +386 -241
  137. package/dist/unpkg/prod-deprecated/adapter/json-api.js +13 -1
  138. package/dist/unpkg/prod-deprecated/adapter/rest.js +39 -3
  139. package/dist/unpkg/prod-deprecated/adapter.js +23 -26
  140. package/dist/unpkg/prod-deprecated/compat/builders.js +0 -1
  141. package/dist/unpkg/prod-deprecated/compat/extensions.js +70 -3
  142. package/dist/unpkg/prod-deprecated/compat/utils.js +14 -0
  143. package/dist/unpkg/prod-deprecated/compat.js +17 -0
  144. package/dist/unpkg/prod-deprecated/{errors-CdDaK81x.js → errors-Dl2J9d1D.js} +24 -1
  145. package/dist/unpkg/prod-deprecated/{hooks-yId87yyG.js → hooks-Cm60wWTf.js} +32 -1
  146. package/dist/unpkg/prod-deprecated/index.js +171 -5
  147. package/dist/unpkg/{dev-deprecated/json-Cu1LNgmQ.js → prod-deprecated/json-Qewu-UN9.js} +63 -19
  148. package/dist/unpkg/prod-deprecated/model/-private.js +1 -1
  149. package/dist/unpkg/prod-deprecated/model/migration-support.js +16 -2
  150. package/dist/{model-for-CqXsIKws.js → unpkg/prod-deprecated/model-for-CXkJw59V.js} +77 -1
  151. package/dist/unpkg/prod-deprecated/model-fragments.js +24 -5
  152. package/dist/unpkg/prod-deprecated/model.js +12 -8
  153. package/dist/unpkg/prod-deprecated/{schema-provider-CjX55uSY.js → schema-provider-Dh6tRqVI.js} +79 -3
  154. package/dist/unpkg/prod-deprecated/serializer/json-api.js +9 -4
  155. package/dist/unpkg/prod-deprecated/serializer/json.js +1 -1
  156. package/dist/unpkg/prod-deprecated/serializer/rest.js +3 -4
  157. package/dist/unpkg/prod-deprecated/serializer/transform.js +51 -3
  158. package/dist/unpkg/prod-deprecated/serializer.js +4 -7
  159. package/dist/unpkg/prod-deprecated/store.js +21 -7
  160. package/package.json +11 -11
  161. package/dist/unpkg/prod/json-BWrZ5546.js +0 -1243
  162. package/dist/unpkg/prod/model-for-CqXsIKws.js +0 -221
@@ -15,6 +15,78 @@ function coerceId(id) {
15
15
  }
16
16
  }
17
17
 
18
+ /**
19
+ Given the name of a relationship on a resource `type`, determines the
20
+ inverse relationship field (if any) using only the schema service.
21
+
22
+ Unlike `Model.inverseFor`, this does not require `type` to be backed by
23
+ a `Model` class, so it works for both `Model`-based and schema-only
24
+ (e.g. `withDefaults` migration-support) resources.
25
+
26
+ @private
27
+ */
28
+ function inverseForRelationship(store, type, name) {
29
+ const relationship = store.schema.fields({
30
+ type
31
+ }).get(name);
32
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
33
+ if (!test) {
34
+ throw new Error(`No relationship named '${name}' on '${type}' exists.`);
35
+ }
36
+ })(relationship) : {};
37
+ const {
38
+ options
39
+ } = relationship;
40
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
41
+ if (!test) {
42
+ throw new Error(`Expected the relationship ${name} on ${type} to define an inverse.`);
43
+ }
44
+ })(options.inverse === null || typeof options.inverse === 'string' && options.inverse.length > 0) : {};
45
+ if (options.inverse === null) {
46
+ return null;
47
+ }
48
+ const schemaExists = store.schema.hasResource(relationship);
49
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
50
+ if (!test) {
51
+ throw new Error(`No associated schema found for '${relationship.type}' while calculating the inverse of ${name} on ${type}`);
52
+ }
53
+ })(schemaExists) : {};
54
+ if (!schemaExists) {
55
+ return null;
56
+ }
57
+ const inverseField = store.schema.fields(relationship).get(options.inverse);
58
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
59
+ if (!test) {
60
+ throw new Error(`No inverse relationship found for '${name}' on '${type}'`);
61
+ }
62
+ })(inverseField && (inverseField.kind === 'belongsTo' || inverseField.kind === 'hasMany')) : {};
63
+ return inverseField ?? null;
64
+ }
65
+
66
+ /**
67
+ Given a relationship field on a resource `type`, determines the
68
+ cardinality of the relationship using only the schema service.
69
+
70
+ Unlike `Model.determineRelationshipType`, this does not require `type`
71
+ to be backed by a `Model` class, so it works for both `Model`-based and
72
+ schema-only (e.g. `withDefaults` migration-support) resources.
73
+
74
+ @private
75
+ */
76
+ function determineRelationshipType(store, type, knownSide) {
77
+ const knownKind = knownSide.kind;
78
+ const inverse = inverseForRelationship(store, type, knownSide.name);
79
+ if (!inverse) {
80
+ return knownKind === 'belongsTo' ? 'oneToNone' : 'manyToNone';
81
+ }
82
+ const otherKind = inverse.kind;
83
+ if (otherKind === 'belongsTo') {
84
+ return knownKind === 'belongsTo' ? 'oneToOne' : 'manyToOne';
85
+ } else {
86
+ return knownKind === 'belongsTo' ? 'oneToMany' : 'manyToMany';
87
+ }
88
+ }
89
+
18
90
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
19
91
  /* eslint-disable @typescript-eslint/no-unsafe-call */
20
92
  /* eslint-disable @typescript-eslint/no-unsafe-return */
@@ -744,9 +816,7 @@ const JSONSerializer = Serializer.extend({
744
816
  */
745
817
  shouldSerializeHasMany(snapshot, key, relationship) {
746
818
  // @ts-expect-error store is dynamically injected
747
- const schema = this.store.modelFor(snapshot.modelName);
748
- // @ts-expect-error store is dynamically injected
749
- const relationshipType = schema.determineRelationshipType(relationship, this.store);
819
+ const relationshipType = determineRelationshipType(this.store, snapshot.modelName, relationship);
750
820
  if (this._mustSerialize(key)) {
751
821
  return true;
752
822
  }
@@ -785,8 +855,15 @@ const JSONSerializer = Serializer.extend({
785
855
  `serialize` takes an options hash with a single option:
786
856
  `includeId`. If this option is `true`, `serialize` will,
787
857
  by default include the ID in the JSON object it builds.
788
- The adapter passes in `includeId: true` when serializing
789
- a record for `createRecord`, but not for `updateRecord`.
858
+ Whether `includeId` is `true` or `false` depends on the
859
+ adapter and the operation being performed, since it is the
860
+ adapter that invokes `serialize` and decides which options
861
+ to pass. For instance, `RESTAdapter` passes `includeId: true`
862
+ when serializing a record for `createRecord`, but not for
863
+ `updateRecord`, while `JSONAPIAdapter` passes `includeId: true`
864
+ for both `createRecord` and `updateRecord`. Refer to the
865
+ documentation for the adapter and serializer pairing you are
866
+ using for specifics.
790
867
  ## Customization
791
868
  Your server may expect a different JSON format than the
792
869
  built-in serialization format.
@@ -1256,4 +1333,4 @@ const JSONSerializer = Serializer.extend({
1256
1333
  return transform;
1257
1334
  }
1258
1335
  });
1259
- export { JSONSerializer as J, coerceId as c };
1336
+ export { JSONSerializer as J, coerceId as c, inverseForRelationship as i };
@@ -1 +1 @@
1
- export { E as Errors, L as LEGACY_SUPPORT, P as PromiseBelongsTo, a as PromiseManyArray, l as lookupLegacySupport } from "../errors-Cz5KrzBk.js";
1
+ export { E as Errors, L as LEGACY_SUPPORT, P as PromiseBelongsTo, a as PromiseManyArray, l as lookupLegacySupport } from "../errors-DZKA206g.js";
@@ -5,8 +5,8 @@ import { notifyInternalSignal } from '@warp-drive/core/signals/-leaked';
5
5
  import { assertPrivateStore } from '@warp-drive/core/store/-private';
6
6
  import { getOrSetGlobal } from '@warp-drive/core/types/-private';
7
7
  import { Type } from '@warp-drive/core/types/symbols';
8
- import { l as lookupLegacySupport, E as Errors } from "../errors-Cz5KrzBk.js";
9
- import { b as buildSchema, u as unloadRecord, s as serialize, _ as _save, a as save, r as rollbackAttributes, c as _reload, d as reload, h as hasMany, e as _destroyRecord, f as destroyRecord, i as deleteRecord, R as RecordState, j as changedAttributes, k as belongsTo, l as createSnapshot } from "../schema-provider-DJCV_6AF.js";
8
+ import { l as lookupLegacySupport, E as Errors } from "../errors-DZKA206g.js";
9
+ import { b as buildSchema, u as unloadRecord, s as serialize, _ as _save, a as save, r as rollbackAttributes, c as _reload, d as reload, h as hasMany, e as _destroyRecord, f as destroyRecord, i as deleteRecord, R as RecordState, j as changedAttributes, k as belongsTo, l as createSnapshot } from "../schema-provider-DtPOp0d7.js";
10
10
  import { macroCondition, getGlobalConfig } from '@embroider/macros';
11
11
 
12
12
  /**
@@ -28,6 +28,11 @@ import { macroCondition, getGlobalConfig } from '@embroider/macros';
28
28
  *
29
29
  * @module
30
30
  */
31
+ /**
32
+ * Adds the `Model`-style `belongsTo`/`hasMany` reference methods to a
33
+ * {@link TypedRecordInstance}, for use when migrating a resource from
34
+ * `Model` to a schema-based record while preserving these APIs.
35
+ */
31
36
  // 'isDestroying', 'isDestroyed'
32
37
  const LegacyFields = ['_createSnapshot', 'adapterError', 'belongsTo', 'changedAttributes', 'constructor', 'currentState', 'deleteRecord', 'destroyRecord', 'dirtyType', 'errors', 'hasDirtyAttributes', 'hasMany', 'isDeleted', 'isEmpty', 'isError', 'isLoaded', 'isLoading', 'isNew', 'isSaving', 'isValid', 'reload', 'rollbackAttributes', 'save', 'serialize', 'unloadRecord'];
33
38
 
@@ -434,6 +439,9 @@ function registerDerivations(schema) {
434
439
  * @public
435
440
  */
436
441
 
442
+ /**
443
+ * See the {@link DelegatingSchemaService | class documentation above} for usage.
444
+ */
437
445
  class DelegatingSchemaService {
438
446
  /** @internal */
439
447
  _preferred;
@@ -443,6 +451,11 @@ class DelegatingSchemaService {
443
451
  this._preferred = schema;
444
452
  this._secondary = buildSchema(store);
445
453
  }
454
+
455
+ /**
456
+ * Whether the given resource's schema is being served by the fallback
457
+ * (legacy Model-derived) schema service rather than the primary one.
458
+ */
446
459
  isDelegated(resource) {
447
460
  return !this._preferred.hasResource(resource) && this._secondary.hasResource(resource);
448
461
  }
@@ -1,6 +1,11 @@
1
1
  import { tracked, cached } from '@glimmer/tracking';
2
2
  import { Context } from '@warp-drive/core/reactive/-private';
3
3
  import { a as decorateFieldV2, i as initializeDeferredDecorator, d as decorateMethodV2 } from "./runtime-BPCpkOf1-BKOwiRJp.js";
4
+
5
+ /**
6
+ * The features added to an object resource by {@link FragmentExtension}, providing
7
+ * a subset of the legacy `ModelFragments` fragment API for migrated resources.
8
+ */
4
9
  class Fragment {
5
10
  static {
6
11
  decorateFieldV2(this.prototype, "isDestroying", [tracked], function () {
@@ -8,12 +13,21 @@ class Fragment {
8
13
  });
9
14
  }
10
15
  #isDestroying = (initializeDeferredDecorator(this, "isDestroying"), void 0); // We might want to check the parent values once we move this code to warp-drive.
16
+ /**
17
+ * Whether this fragment is in the process of being destroyed.
18
+ */
11
19
  static {
12
20
  decorateFieldV2(this.prototype, "isDestroyed", [tracked], function () {
13
21
  return false;
14
22
  });
15
23
  }
16
24
  #isDestroyed = (initializeDeferredDecorator(this, "isDestroyed"), void 0);
25
+ /**
26
+ * Whether this fragment has been destroyed.
27
+ */
28
+ /**
29
+ * Whether this fragment (or the attribute it is rooted at) has uncommitted changes.
30
+ */
17
31
  get hasDirtyAttributes() {
18
32
  const {
19
33
  path,
@@ -27,18 +41,30 @@ class Fragment {
27
41
  }
28
42
  return false;
29
43
  }
44
+
45
+ /**
46
+ * Always `true`. Used to distinguish fragments from other resources.
47
+ */
30
48
  static {
31
49
  decorateMethodV2(this.prototype, "hasDirtyAttributes", [cached]);
32
50
  }
33
51
  get isFragment() {
34
52
  return true;
35
53
  }
54
+
55
+ /**
56
+ * The resource type of this fragment, if known.
57
+ */
36
58
  get $type() {
37
59
  const {
38
60
  field
39
61
  } = this[Context];
40
62
  return field?.type;
41
63
  }
64
+
65
+ /**
66
+ * Reverts this fragment's attribute back to its last known remote value.
67
+ */
42
68
  rollbackAttributes() {
43
69
  const {
44
70
  path,
@@ -51,11 +77,21 @@ class Fragment {
51
77
  }
52
78
  }
53
79
  }
80
+
81
+ /**
82
+ * A schema extension that adds the {@link Fragment} API to migrated
83
+ * `ModelFragments` object resources.
84
+ */
54
85
  const FragmentExtension = {
55
86
  kind: 'object',
56
87
  name: 'fragment',
57
88
  features: Fragment
58
89
  };
90
+
91
+ /**
92
+ * The features added to an array resource by {@link FragmentArrayExtension}, providing
93
+ * a subset of the legacy `ModelFragments` fragment-array API for migrated resources.
94
+ */
59
95
  class FragmentArray {
60
96
  static {
61
97
  decorateFieldV2(this.prototype, "isDestroying", [tracked], function () {
@@ -63,18 +99,29 @@ class FragmentArray {
63
99
  });
64
100
  }
65
101
  #isDestroying = (initializeDeferredDecorator(this, "isDestroying"), void 0); // We might want to check the parent values once we move this code to warp-drive.
102
+ /**
103
+ * Whether this fragment array is in the process of being destroyed.
104
+ */
66
105
  static {
67
106
  decorateFieldV2(this.prototype, "isDestroyed", [tracked], function () {
68
107
  return false;
69
108
  });
70
109
  }
71
110
  #isDestroyed = (initializeDeferredDecorator(this, "isDestroyed"), void 0);
111
+ /**
112
+ * Whether this fragment array has been destroyed.
113
+ */
114
+ /**
115
+ * Whether this fragment array (or any of its members) has uncommitted changes.
116
+ */
72
117
  get hasDirtyAttributes() {
118
+ const array = this;
119
+ const context = array[Context];
73
120
  const {
74
121
  path,
75
122
  resourceKey,
76
123
  store
77
- } = this[Context];
124
+ } = context;
78
125
  const record = store.peekRecord(resourceKey);
79
126
  if (record.hasDirtyAttributes && path) {
80
127
  const root = path.at(0);
@@ -82,6 +129,10 @@ class FragmentArray {
82
129
  }
83
130
  return false;
84
131
  }
132
+
133
+ /**
134
+ * Adds an existing fragment to this array, if one was given.
135
+ */
85
136
  static {
86
137
  decorateMethodV2(this.prototype, "hasDirtyAttributes", [cached]);
87
138
  }
@@ -91,12 +142,20 @@ class FragmentArray {
91
142
  }
92
143
  return this.addObject(fragment);
93
144
  }
145
+
146
+ /**
147
+ * Appends a new fragment to the end of this array, if one was given.
148
+ */
94
149
  createFragment(fragment) {
95
150
  if (!fragment) {
96
151
  return;
97
152
  }
98
153
  return this.pushObject(fragment);
99
154
  }
155
+
156
+ /**
157
+ * Removes the given fragment from this array, if present.
158
+ */
100
159
  removeFragment(fragment) {
101
160
  if (!fragment) {
102
161
  return;
@@ -106,6 +165,10 @@ class FragmentArray {
106
165
  this.splice(index, 1);
107
166
  }
108
167
  }
168
+
169
+ /**
170
+ * Reverts each member fragment's attribute back to its last known remote value.
171
+ */
109
172
  rollbackAttributes() {
110
173
  for (const fragment of this) {
111
174
  // @ts-expect-error TODO: fix these types
@@ -113,6 +176,11 @@ class FragmentArray {
113
176
  }
114
177
  }
115
178
  }
179
+
180
+ /**
181
+ * A schema extension that adds the {@link FragmentArray} API to migrated
182
+ * `ModelFragments` array resources.
183
+ */
116
184
  const FragmentArrayExtension = {
117
185
  kind: 'array',
118
186
  name: 'fragment-array',
@@ -217,5 +285,13 @@ class ShimModelClass {
217
285
  function fragmentsModelFor(modelName) {
218
286
  return getShimClass(this, modelName);
219
287
  }
288
+
289
+ /**
290
+ * The `modelFor` fallback used to construct a `ShimModelClass` schema for a
291
+ * type when ModelFragments support is enabled and no real `Model` subclass
292
+ * is registered for that type.
293
+ *
294
+ * @public
295
+ */
220
296
  const modelFor = fragmentsModelFor;
221
297
  export { FragmentExtension as F, FragmentArrayExtension as a, FragmentArray as b, Fragment as c, fragmentsModelFor as f, modelFor as m };
@@ -1,20 +1,23 @@
1
- import { singularize, pluralize } from '@warp-drive/utilities/string';
1
+ import { pluralize, singularize } from '@warp-drive/utilities/string';
2
2
  import { withDefaults } from './model/migration-support.js';
3
- import { F as FragmentExtension, a as FragmentArrayExtension } from "./model-for-CqXsIKws.js";
4
- export { c as Fragment, b as FragmentArray, m as modelFor } from "./model-for-CqXsIKws.js";
3
+ import { F as FragmentExtension, a as FragmentArrayExtension } from "./model-for-CXkJw59V.js";
4
+ export { c as Fragment, b as FragmentArray, m as modelFor } from "./model-for-CXkJw59V.js";
5
5
 
6
6
  /**
7
7
  * Used as a helper to setup the relevant parts of an array
8
8
  * schema and add extensions etc.
9
9
  *
10
10
  * @param arrayName The name of the array
11
+ * @param primitiveType The primitive type of items in the array (optional)
11
12
  * @returns The schema for an array
12
13
  */
13
- function withArrayDefaults(arrayName) {
14
+
15
+ function withArrayDefaults(arrayName, primitiveType) {
16
+ const type = primitiveType ? `array:${primitiveType}` : 'array';
14
17
  return {
15
18
  kind: 'array',
16
19
  name: arrayName,
17
- type: `array:${singularize(arrayName)}`,
20
+ type,
18
21
  options: {
19
22
  arrayExtensions: ['ember-object', 'ember-array-like', 'fragment-array']
20
23
  }
@@ -59,6 +62,15 @@ function withFragmentArrayDefaults(fragmentArrayType, fragmentArrayName) {
59
62
  }
60
63
  };
61
64
  }
65
+
66
+ /**
67
+ * Used as a helper to setup the relevant parts of a legacy resource schema
68
+ * migrated from `Model`, applying the `ember-object` and `fragment` object
69
+ * extensions and a default `@id` identity field.
70
+ *
71
+ * @param schema the partial legacy resource schema to complete
72
+ * @returns the completed resource schema
73
+ */
62
74
  function withLegacy(schema) {
63
75
  return withDefaults({
64
76
  ...schema,
@@ -69,6 +81,13 @@ function withLegacy(schema) {
69
81
  objectExtensions: ['ember-object', 'fragment']
70
82
  });
71
83
  }
84
+
85
+ /**
86
+ * Registers the {@link FragmentExtension}/{@link FragmentArrayExtension} schema
87
+ * extensions on the given `SchemaService`, enabling ModelFragments migration support.
88
+ *
89
+ * @public
90
+ */
72
91
  function registerFragmentExtensions(schema) {
73
92
  schema.CAUTION_MEGA_DANGER_ZONE_registerExtension?.(FragmentExtension);
74
93
  schema.CAUTION_MEGA_DANGER_ZONE_registerExtension?.(FragmentArrayExtension);
package/dist/model.js CHANGED
@@ -5,10 +5,10 @@ import { i as isElementDescriptor, n as normalizeModelName } from "./util-Dul6TZ
5
5
  import { macroCondition, getGlobalConfig } from '@embroider/macros';
6
6
  import { warn, deprecate } from '@ember/debug';
7
7
  import { assertPrivateStore } from '@warp-drive/core/store/-private';
8
- import { l as lookupLegacySupport } from "./errors-Cz5KrzBk.js";
8
+ import { l as lookupLegacySupport } from "./errors-DZKA206g.js";
9
9
  import { singularize, dasherize } from '@warp-drive/utilities/string';
10
- export { M as Model, b as buildSchema, M as default, m as restoreDeprecatedModelRequestBehaviors } from "./schema-provider-DJCV_6AF.js";
11
- export { i as instantiateRecord, m as modelFor, t as teardownRecord } from "./hooks-D6diaM34.js";
10
+ export { M as Model, b as buildSchema, M as default, m as restoreDeprecatedModelRequestBehaviors } from "./schema-provider-DtPOp0d7.js";
11
+ export { i as instantiateRecord, m as modelFor, t as teardownRecord } from "./hooks-BvOqJBei.js";
12
12
  function _attr(type, options) {
13
13
  if (typeof type === 'object') {
14
14
  options = type;
@@ -21,6 +21,7 @@ function _attr(type, options) {
21
21
  kind: 'attribute',
22
22
  isAttribute: true,
23
23
  options: options,
24
+ sourceKey: options.sourceKey,
24
25
  key: null
25
26
  };
26
27
  return computed({
@@ -34,7 +35,7 @@ function _attr(type, options) {
34
35
  return;
35
36
  }
36
37
  const cache = this[RecordStore].cache;
37
- return cache.getAttr(recordIdentifierFor(this), key);
38
+ return cache.getAttr(recordIdentifierFor(this), meta.sourceKey ?? key);
38
39
  },
39
40
  set(key, value) {
40
41
  if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
@@ -49,9 +50,10 @@ function _attr(type, options) {
49
50
  }
50
51
  })(!this.currentState.isDeleted) : {};
51
52
  const cache = this[RecordStore].cache;
52
- const currentValue = cache.getAttr(identifier, key);
53
+ const cacheKey = meta.sourceKey ?? key;
54
+ const currentValue = cache.getAttr(identifier, cacheKey);
53
55
  if (currentValue !== value) {
54
- cache.setAttr(identifier, key, value);
56
+ cache.setAttr(identifier, cacheKey, value);
55
57
  if (!this.isValid) {
56
58
  const {
57
59
  errors
@@ -202,7 +204,8 @@ function _belongsTo(type, options) {
202
204
  type: normalizeModelName(type),
203
205
  options: options,
204
206
  kind: 'belongsTo',
205
- name: '<Unknown BelongsTo>'
207
+ name: '<Unknown BelongsTo>',
208
+ sourceKey: options.sourceKey
206
209
  };
207
210
  return computed({
208
211
  get(key) {
@@ -456,7 +459,8 @@ function _hasMany(type, options) {
456
459
  type: normalizeType(type),
457
460
  options,
458
461
  kind: 'hasMany',
459
- name: '<Unknown BelongsTo>'
462
+ name: '<Unknown BelongsTo>',
463
+ sourceKey: options.sourceKey
460
464
  };
461
465
  return computed({
462
466
  get(key) {