@warp-drive-mirror/core 5.10.0-alpha.21 → 5.10.0-alpha.23

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 (133) hide show
  1. package/dist/{-private-CvZfrDZl.js → -private-DhEjiHue.js} +2 -2
  2. package/dist/{-private-CvZfrDZl.js.map → -private-DhEjiHue.js.map} +1 -1
  3. package/dist/build-config/babel-macros.d.ts +5 -0
  4. package/dist/build-config/canary-features.d.ts +5 -0
  5. package/dist/build-config/debugging.d.ts +59 -0
  6. package/dist/build-config/deprecations.d.ts +5 -0
  7. package/dist/build-config.d.ts +17 -0
  8. package/dist/{concepts-vh86nAcd.d.ts → concepts-Db9ssz1h.d.ts} +3 -3
  9. package/dist/{concepts-vh86nAcd.d.ts.map → concepts-Db9ssz1h.d.ts.map} +1 -1
  10. package/dist/configure.d.ts +8 -0
  11. package/dist/configure.js +1 -1
  12. package/dist/{document-B8Fup751.d.ts → document-BUmwSPVO.d.ts} +2 -2
  13. package/dist/{document-B8Fup751.d.ts.map → document-BUmwSPVO.d.ts.map} +1 -1
  14. package/dist/{fields-r1rZJB9d.d.ts → fields-B-jO-dzB.d.ts} +111 -47
  15. package/dist/fields-B-jO-dzB.d.ts.map +1 -0
  16. package/dist/graph/-private.d.ts +1 -1
  17. package/dist/graph/-private.js +33 -20
  18. package/dist/graph/-private.js.map +1 -1
  19. package/dist/{graph-BqxaFjEb.d.ts → graph-CoQhsOgT.d.ts} +3 -3
  20. package/dist/{graph-BqxaFjEb.d.ts.map → graph-CoQhsOgT.d.ts.map} +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.js +1 -1
  23. package/dist/{internal-D_WIXC4r.d.ts → internal-BrC3kM86.d.ts} +20 -6
  24. package/dist/internal-BrC3kM86.d.ts.map +1 -0
  25. package/dist/reactive/-private.d.ts +1 -1
  26. package/dist/reactive.d.ts +276 -1
  27. package/dist/reactive.js +2 -2
  28. package/dist/{request-CxtnNIIp.js → request-qKqD2aCa.js} +2 -2
  29. package/dist/{request-CxtnNIIp.js.map → request-qKqD2aCa.js.map} +1 -1
  30. package/dist/request.d.ts +9 -1
  31. package/dist/request.js +1 -1
  32. package/dist/signals/-leaked.d.ts +15 -1
  33. package/dist/signals/-leaked.d.ts.map +1 -1
  34. package/dist/signals/-leaked.js +1 -1
  35. package/dist/{src-ccp1WKyt.js → src-spa19bCt.js} +30 -13
  36. package/dist/src-spa19bCt.js.map +1 -0
  37. package/dist/store/-private.d.ts +1 -1
  38. package/dist/store/-private.js +1 -1
  39. package/dist/store.d.ts +6 -1
  40. package/dist/types/-private.js +1 -1
  41. package/dist/types/cache/relationship.d.ts +5 -0
  42. package/dist/types/cache.d.ts +6 -1
  43. package/dist/types/graph.d.ts +6 -1
  44. package/dist/types/record.d.ts +5 -0
  45. package/dist/types/request.d.ts +1 -1
  46. package/dist/types/schema/concepts.d.ts +6 -1
  47. package/dist/types/schema/fields.d.ts +2 -2
  48. package/dist/types/schema/fields.js +82 -23
  49. package/dist/types/schema/fields.js.map +1 -1
  50. package/dist/types/schema/schema-service.d.ts +6 -1
  51. package/dist/types/spec/document.d.ts +1 -1
  52. package/dist/types/spec/error.d.ts +4 -0
  53. package/dist/types/spec/json-api-raw.d.ts +5 -0
  54. package/dist/types.d.ts +9 -1
  55. package/dist/unpkg/{dev-deprecated/-private-B4pCmkq-.js → dev/-private-BJ2WIhKs.js} +2 -2
  56. package/dist/unpkg/dev/{-private-B4pCmkq-.js.map → -private-BJ2WIhKs.js.map} +1 -1
  57. package/dist/unpkg/dev/configure.js +1 -1
  58. package/dist/unpkg/dev/graph/-private.js +34 -21
  59. package/dist/unpkg/dev/graph/-private.js.map +1 -1
  60. package/dist/unpkg/dev/index.js +1 -1
  61. package/dist/unpkg/dev/reactive.js +2 -2
  62. package/dist/unpkg/dev/{request-oWpijCPQ.js → request-6lzVjHLN.js} +2 -2
  63. package/dist/unpkg/{dev-deprecated/request-oWpijCPQ.js.map → dev/request-6lzVjHLN.js.map} +1 -1
  64. package/dist/unpkg/dev/request.js +1 -1
  65. package/dist/unpkg/dev/signals/-leaked.js +1 -1
  66. package/dist/unpkg/dev/{src-C4ET4R1n.js → src-D1dbEzXb.js} +31 -14
  67. package/dist/unpkg/dev/src-D1dbEzXb.js.map +1 -0
  68. package/dist/unpkg/dev/store/-private.js +1 -1
  69. package/dist/unpkg/dev/{store-dZViNfMK.js → store-DVS3G92Q.js} +2 -2
  70. package/dist/unpkg/dev/{store-dZViNfMK.js.map → store-DVS3G92Q.js.map} +1 -1
  71. package/dist/unpkg/dev/store.js +1 -1
  72. package/dist/unpkg/dev/types/-private.js +1 -1
  73. package/dist/unpkg/dev/types/schema/fields.js +82 -23
  74. package/dist/unpkg/dev/types/schema/fields.js.map +1 -1
  75. package/dist/unpkg/{dev/-private-B4pCmkq-.js → dev-deprecated/-private-BJ2WIhKs.js} +2 -2
  76. package/dist/unpkg/dev-deprecated/{-private-B4pCmkq-.js.map → -private-BJ2WIhKs.js.map} +1 -1
  77. package/dist/unpkg/dev-deprecated/configure.js +1 -1
  78. package/dist/unpkg/dev-deprecated/graph/-private.js +34 -21
  79. package/dist/unpkg/dev-deprecated/graph/-private.js.map +1 -1
  80. package/dist/unpkg/dev-deprecated/index.js +1 -1
  81. package/dist/unpkg/dev-deprecated/reactive.js +2 -2
  82. package/dist/unpkg/dev-deprecated/{request-oWpijCPQ.js → request-6lzVjHLN.js} +2 -2
  83. package/dist/unpkg/{dev/request-oWpijCPQ.js.map → dev-deprecated/request-6lzVjHLN.js.map} +1 -1
  84. package/dist/unpkg/dev-deprecated/request.js +1 -1
  85. package/dist/unpkg/dev-deprecated/signals/-leaked.js +1 -1
  86. package/dist/unpkg/dev-deprecated/{src-jHpowq3S.js → src-Tvv7X1KB.js} +30 -13
  87. package/dist/unpkg/dev-deprecated/src-Tvv7X1KB.js.map +1 -0
  88. package/dist/unpkg/dev-deprecated/store/-private.js +1 -1
  89. package/dist/unpkg/dev-deprecated/types/-private.js +1 -1
  90. package/dist/unpkg/dev-deprecated/types/schema/fields.js +82 -23
  91. package/dist/unpkg/dev-deprecated/types/schema/fields.js.map +1 -1
  92. package/dist/unpkg/{prod-deprecated/-private-CrUi_3E_.js → prod/-private-Dg07O05r.js} +2 -2
  93. package/dist/unpkg/{prod-deprecated/-private-CrUi_3E_.js.map → prod/-private-Dg07O05r.js.map} +1 -1
  94. package/dist/unpkg/prod/configure.js +1 -1
  95. package/dist/unpkg/prod/graph/-private.js +27 -12
  96. package/dist/unpkg/prod/graph/-private.js.map +1 -1
  97. package/dist/unpkg/prod/index.js +1 -1
  98. package/dist/unpkg/prod/reactive.js +2 -2
  99. package/dist/unpkg/{prod-deprecated/request-Cgw3j6Dx.js → prod/request-edWLn9JK.js} +2 -2
  100. package/dist/unpkg/prod/{request-Cgw3j6Dx.js.map → request-edWLn9JK.js.map} +1 -1
  101. package/dist/unpkg/prod/request.js +1 -1
  102. package/dist/unpkg/prod/signals/-leaked.js +1 -1
  103. package/dist/unpkg/prod/{src-DFmPDGQ6.js → src-BIRx6kC-.js} +33 -12
  104. package/dist/unpkg/prod/src-BIRx6kC-.js.map +1 -0
  105. package/dist/unpkg/prod/store/-private.js +1 -1
  106. package/dist/unpkg/prod/types/-private.js +1 -1
  107. package/dist/unpkg/prod/types/schema/fields.js +82 -23
  108. package/dist/unpkg/prod/types/schema/fields.js.map +1 -1
  109. package/dist/unpkg/{prod/-private-CrUi_3E_.js → prod-deprecated/-private-Dg07O05r.js} +2 -2
  110. package/dist/unpkg/{prod/-private-CrUi_3E_.js.map → prod-deprecated/-private-Dg07O05r.js.map} +1 -1
  111. package/dist/unpkg/prod-deprecated/configure.js +1 -1
  112. package/dist/unpkg/prod-deprecated/graph/-private.js +27 -12
  113. package/dist/unpkg/prod-deprecated/graph/-private.js.map +1 -1
  114. package/dist/unpkg/prod-deprecated/index.js +1 -1
  115. package/dist/unpkg/prod-deprecated/reactive.js +2 -2
  116. package/dist/unpkg/{prod/request-Cgw3j6Dx.js → prod-deprecated/request-edWLn9JK.js} +2 -2
  117. package/dist/unpkg/prod-deprecated/{request-Cgw3j6Dx.js.map → request-edWLn9JK.js.map} +1 -1
  118. package/dist/unpkg/prod-deprecated/request.js +1 -1
  119. package/dist/unpkg/prod-deprecated/signals/-leaked.js +1 -1
  120. package/dist/unpkg/prod-deprecated/{src-BgQLcshl.js → src-0f4an0QR.js} +33 -12
  121. package/dist/unpkg/prod-deprecated/src-0f4an0QR.js.map +1 -0
  122. package/dist/unpkg/prod-deprecated/store/-private.js +1 -1
  123. package/dist/unpkg/prod-deprecated/types/-private.js +1 -1
  124. package/dist/unpkg/prod-deprecated/types/schema/fields.js +82 -23
  125. package/dist/unpkg/prod-deprecated/types/schema/fields.js.map +1 -1
  126. package/package.json +4 -4
  127. package/dist/fields-r1rZJB9d.d.ts.map +0 -1
  128. package/dist/internal-D_WIXC4r.d.ts.map +0 -1
  129. package/dist/src-ccp1WKyt.js.map +0 -1
  130. package/dist/unpkg/dev/src-C4ET4R1n.js.map +0 -1
  131. package/dist/unpkg/dev-deprecated/src-jHpowq3S.js.map +0 -1
  132. package/dist/unpkg/prod/src-DFmPDGQ6.js.map +0 -1
  133. package/dist/unpkg/prod-deprecated/src-BgQLcshl.js.map +0 -1
@@ -1,2 +1,7 @@
1
+ /**
2
+ * @module
3
+ * @summary The `macros` function, which returns the Babel plugins that strip WarpDrive deprecation, canary-feature,
4
+ * debug-logging and env code at build time.
5
+ */
1
6
  import { macros } from "@warp-drive-mirror/build-config/babel-macros";
2
7
  export { macros };
@@ -1 +1,6 @@
1
+ /**
2
+ * @module
3
+ * @summary Build-time flags, such as `JSON_API_CACHE_VALIDATION_ERRORS`, that gate unreleased WarpDrive features for
4
+ * canary builds.
5
+ */
1
6
  export * from "@warp-drive-mirror/build-config/canary-features";
@@ -1 +1,60 @@
1
+ /**
2
+ * # Log Instrumentation <Badge type="tip" text="debug only" />
3
+ *
4
+ * Many portions of the internals are helpfully instrumented with logging.
5
+ * This instrumentation is always removed from production builds.
6
+ *
7
+ * The [Debugging](/guides/the-manual/debugging/) guide explains what each flag logs.
8
+ *
9
+ * Log instrumentation is "regionalized" to specific concepts and concerns
10
+ * to enable you to enable/disable just the areas you are interested in.
11
+ *
12
+ * To activate a particular group of logs set the appropriate flag to `true`
13
+ * either in your build config or via the runtime helper.
14
+ *
15
+ *
16
+ * ## Runtime Activation
17
+ *
18
+ * ::: tip 💡 Just Works in browser Dev Tools!
19
+ * No import is needed, and the logging config is preserved when the page is refreshed
20
+ * :::
21
+ *
22
+ * ```ts
23
+ * setWarpDriveLogging({
24
+ * LOG_CACHE: true,
25
+ * LOG_REQUESTS: true,
26
+ * })
27
+ * ```
28
+ *
29
+ * A runtime helper is attached to `globalThis` to enable activation of the logs
30
+ * from anywhere in your application including from the devtools panel.
31
+ *
32
+ * The runtime helper overrides any build config settings for the given flag
33
+ * for the current browser tab. It stores the configuration you give it in
34
+ * `sessionStorage` so that it persists across page reloads of the current tab,
35
+ * but not across browser tabs or windows.
36
+ *
37
+ * If you need to deactivate the logging, you can call the helper again with the
38
+ * same flag set to `false` or just open a new tab/window.
39
+ *
40
+ * ## Buildtime Activation
41
+ *
42
+ * ```ts
43
+ * setConfig(__dirname, app, {
44
+ * debug: {
45
+ * LOG_CACHE: true,
46
+ * LOG_REQUESTS: false,
47
+ * LOG_NOTIFICATIONS: true,
48
+ * }
49
+ * });
50
+ * ```
51
+ *
52
+ * The build config settings are used to set the default values for the
53
+ * logging flags. Any logging flag that is not set in the build config
54
+ * will default to `false`.
55
+ *
56
+ * @summary Debug-only logging flags, such as `LOG_CACHE` and `LOG_REQUESTS`, set in build config or at runtime
57
+ * via `setWarpDriveLogging`.
58
+ * @module
59
+ */
1
60
  export * from "@warp-drive-mirror/build-config/debugging";
@@ -1 +1,6 @@
1
+ /**
2
+ * @module
3
+ * @summary Deprecation flags, such as `DEPRECATE_NON_STRICT_TYPES`, that keep deprecated WarpDrive behavior active
4
+ * until the build config drops it by `compatWith` version or by flag.
5
+ */
1
6
  export * from "@warp-drive-mirror/build-config/deprecations";
@@ -1,2 +1,19 @@
1
+ /**
2
+ * This module provides a build-plugin that enables configuration of deprecations,
3
+ * optional features, development/testing support and debug logging.
4
+ *
5
+ * Available settings include:
6
+ *
7
+ * - {@link LOGGING | debugging}
8
+ * - {@link DEPRECATIONS | deprecations}
9
+ * - {@link FEATURES | features}
10
+ * - {@link WarpDriveConfig.polyfillUUID | polyfillUUID}
11
+ * - {@link WarpDriveConfig.includeDataAdapterInProduction | includeDataAdapterInProduction}
12
+ * - {@link WarpDriveConfig.compatWith | compatWith}
13
+ *
14
+ * @summary Build-time configuration for WarpDrive: `setConfig` and its babel plugin for deprecations, features,
15
+ * debug logging, and polyfill settings.
16
+ * @module
17
+ */
1
18
  import { WarpDriveConfig, babelPlugin, setConfig } from "@warp-drive-mirror/build-config";
2
19
  export { type WarpDriveConfig, babelPlugin, setConfig };
@@ -1,7 +1,7 @@
1
1
  import { l as ResourceKey } from "./identifier-DmgDehQK.js";
2
- import { a as Type } from "./symbols-DVa1PMFG.js";
3
- import { i as OpaqueRecordInstance } from "./record-f5-uOgHt.js";
4
2
  import { i as Value, n as ObjectValue } from "./raw-adYGuEGM.js";
3
+ import { i as OpaqueRecordInstance } from "./record-f5-uOgHt.js";
4
+ import { a as Type } from "./symbols-DVa1PMFG.js";
5
5
  /**
6
6
  * A Transformation converts a cached primitive value into a richer
7
7
  * "presentation" value exposed on a record, and back again.
@@ -81,4 +81,4 @@ type HashFn<T extends object = object> = {
81
81
  [Type]: string;
82
82
  } & ((data: T, options: ObjectValue | null, prop: string | null) => string);
83
83
  export { HashFn as n, Transformation as r, Derivation as t };
84
- //# sourceMappingURL=concepts-vh86nAcd.d.ts.map
84
+ //# sourceMappingURL=concepts-Db9ssz1h.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"concepts-vh86nAcd.d.ts","names":[],"sources":["../src/types/schema/concepts.ts"],"mappings":";;;;;;;;;;;;;;;;;;;KA0BY,eAAe,UAAU,QAAQ,OAAO;;;;;EAKlD,UAAU,OAAO,IAAI,SAAS,oBAAoB,QAAQ,uBAAuB;;;;;EAMjF,QAAQ,OAAO,eAAe,SAAS,oBAAoB,QAAQ,uBAAuB;;;;;EAM1F,cAAc,SAAS,oBAAoB,YAAY,cAAc;;;;GAKpE;;;;;;;;;;;;;;;;;KAkBS,WAAW,aAAa,aAAa,WAAW,qBAAqB;;;;GAI9E;MACG,QAAQ,GAAG,SAAS,IAAI,iBAAiB;;;;;;;;;;;;;;;;KAiBnC,OAAO;;;;GAIhB;MACG,MAAM,GAAG,SAAS,oBAAoB"}
1
+ {"version":3,"file":"concepts-Db9ssz1h.d.ts","names":[],"sources":["../src/types/schema/concepts.ts"],"mappings":";;;;;;;;;;;;;;;;;;;KA0BY,eAAe,UAAU,QAAQ,OAAO;;;;;EAKlD,UAAU,OAAO,IAAI,SAAS,oBAAoB,QAAQ,uBAAuB;;;;;EAMjF,QAAQ,OAAO,eAAe,SAAS,oBAAoB,QAAQ,uBAAuB;;;;;EAM1F,cAAc,SAAS,oBAAoB,YAAY,cAAc;;;;GAKpE;;;;;;;;;;;;;;;;;KAkBS,WAAW,aAAa,aAAa,WAAW,qBAAqB;;;;GAI9E;MACG,QAAQ,GAAG,SAAS,IAAI,iBAAiB;;;;;;;;;;;;;;;;KAiBnC,OAAO;;;;GAIhB;MACG,MAAM,GAAG,SAAS,oBAAoB"}
@@ -1,2 +1,10 @@
1
+ /**
2
+ * Provides a configuration API for the reactivity system
3
+ * that WarpDrive should use.
4
+ *
5
+ * @summary Provides `setupSignals`, which tells WarpDrive which signal and reactivity library to build its
6
+ * reactive values on.
7
+ * @module
8
+ */
1
9
  import { a as registerSignals, n as HooksOptions, o as setupSignals, r as SignalHooks } from "./configure-BfXDuPUb.js";
2
10
  export { type HooksOptions, type SignalHooks, registerSignals, setupSignals };
package/dist/configure.js CHANGED
@@ -1,3 +1,3 @@
1
- import { M as registerSignals, N as setupSignals } from "./-private-CvZfrDZl.js";
1
+ import { M as registerSignals, N as setupSignals } from "./-private-DhEjiHue.js";
2
2
 
3
3
  export { registerSignals, setupSignals };
@@ -1,6 +1,6 @@
1
1
  import { s as PersistedResourceKey } from "./identifier-DmgDehQK.js";
2
- import { d as Meta, m as PaginationLinks, u as Links } from "./json-api-raw-juUdIITO.js";
3
2
  import { t as ApiError } from "./error-j5n1yL9m.js";
3
+ import { d as Meta, m as PaginationLinks, u as Links } from "./json-api-raw-juUdIITO.js";
4
4
  /**
5
5
  * This type represents a raw {json:api} document for a meta-only
6
6
  * document returned by a request intended to be inserted into the cache.
@@ -142,4 +142,4 @@ interface ResourceErrorDocument {
142
142
  */
143
143
  type ResourceDocument<T = PersistedResourceKey> = ResourceMetaDocument | SingleResourceDataDocument<T> | CollectionResourceDataDocument<T> | ResourceErrorDocument;
144
144
  export { ResourceMetaDocument as a, ResourceErrorDocument as i, ResourceDataDocument as n, SingleResourceDataDocument as o, ResourceDocument as r, CollectionResourceDataDocument as t };
145
- //# sourceMappingURL=document-B8Fup751.d.ts.map
145
+ //# sourceMappingURL=document-BUmwSPVO.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"document-B8Fup751.d.ts","names":[],"sources":["../src/types/spec/document.ts"],"mappings":";;;;;;;;;;UAmBiB;;;;EAIf;;;;EAIA,MAAM;;;;EAIN,QAAQ,QAAQ;;;;;;;;;;;UAYD,2BAA2B,IAAI,sBAAsB,IAAI;;;;EAIxE;;;;EAIA,QAAQ,QAAQ;;;;EAIhB,OAAO;;;;EAIP,MAAM;;;;EAIN,WAAW;;;;;;;;;;;UAYI,+BAA+B,IAAI;;;;EAIlD;;;;EAIA,QAAQ,QAAQ;;;;EAIhB,OAAO;;;;EAIP,MAAM;;;;EAIN,WAAW;;;;;;;;;;;;;;;KAgBD,qBAAqB,IAAI,wBACjC,2BAA2B,KAC3B,+BAA+B;;;;;;;;;;UAWlB;;;;EAIf;;;;EAIA,QAAQ,QAAQ;;;;EAIhB,OAAO;;;;EAIP,QAAQ;;;;;;;;;;;;;;;;;KAkBE,iBAAiB,IAAI,wBAC7B,uBACA,2BAA2B,KAC3B,+BAA+B,KAC/B"}
1
+ {"version":3,"file":"document-BUmwSPVO.d.ts","names":[],"sources":["../src/types/spec/document.ts"],"mappings":";;;;;;;;;;UAmBiB;;;;EAIf;;;;EAIA,MAAM;;;;EAIN,QAAQ,QAAQ;;;;;;;;;;;UAYD,2BAA2B,IAAI,sBAAsB,IAAI;;;;EAIxE;;;;EAIA,QAAQ,QAAQ;;;;EAIhB,OAAO;;;;EAIP,MAAM;;;;EAIN,WAAW;;;;;;;;;;;UAYI,+BAA+B,IAAI;;;;EAIlD;;;;EAIA,QAAQ,QAAQ;;;;EAIhB,OAAO;;;;EAIP,MAAM;;;;EAIN,WAAW;;;;;;;;;;;;;;;KAgBD,qBAAqB,IAAI,wBACjC,2BAA2B,KAC3B,+BAA+B;;;;;;;;;;UAWlB;;;;EAIf;;;;EAIA,QAAQ,QAAQ;;;;EAIhB,OAAO;;;;EAIP,QAAQ;;;;;;;;;;;;;;;;;KAkBE,iBAAiB,IAAI,wBAC7B,uBACA,2BAA2B,KAC3B,+BAA+B,KAC/B"}
@@ -963,16 +963,29 @@ interface DerivedField {
963
963
  * Represents a field that is a reference to
964
964
  * another resource.
965
965
  *
966
- * SUPPORT FOR THIS FEATURE IS NOT YET COMPLETE
967
- * IN ReactiveResource. It is not yet part of
968
- * {@link PolarisModeFieldSchema} or {@link LegacyModeFieldSchema}.
969
- * Reading the field returns an object with the related
970
- * record as `data`, plus `links`, `meta` and a `fetch()`
971
- * method, but it does not yet update when the
972
- * relationship changes, and setting it is not supported.
973
- *
974
- * @summary Field schema of kind `resource` for a reference to another resource; not yet implemented by
975
- * `ReactiveResource`.
966
+ * The value of a `resource` field on a ReactiveResource is a
967
+ * `ReactiveRelationshipDocument` whose `data` is the related
968
+ * resource (or `null`), and whose `links` and `meta` mirror the
969
+ * relationship payload received from the API.
970
+ *
971
+ * ```ts
972
+ * const user = store.peekRecord<User>('user', '1');
973
+ * user.bestFriend.data; // User | null | undefined
974
+ * user.bestFriend.links; // { related: '/users/1/best-friend' }
975
+ * ```
976
+ *
977
+ * The relationship payload for this field is expected to have the
978
+ * shape `{ data?: { type, id } | null, links?: Links, meta?: Meta }`.
979
+ * When `data` is omitted from the payload `doc.data` is `undefined`
980
+ * and `doc.fetch()` may be used to load the related resource via
981
+ * the `related` link.
982
+ *
983
+ * In LegacyMode the relationship is mutable via `doc.data = record`.
984
+ * In PolarisMode it is immutable unless the parent resource has been
985
+ * checked out for editing.
986
+ *
987
+ * @summary Field schema of kind `resource` for a reference to another resource, whose value is a
988
+ * `ReactiveRelationshipDocument`.
976
989
  * @public
977
990
  */
978
991
  interface ResourceField {
@@ -1029,12 +1042,22 @@ interface ResourceField {
1029
1042
  */
1030
1043
  options?: {
1031
1044
  /**
1032
- * Whether the relationship is async
1045
+ * Whether the relationship is async.
1033
1046
  *
1034
- * If true, it is expected that the cache
1035
- * data for this field will contain a link
1036
- * that can be used to fetch the related
1037
- * resource when needed.
1047
+ * For `resource` fields `async` describes what the API
1048
+ * sends for the relationship (see the Relationship
1049
+ * Specification in the manual):
1050
+ *
1051
+ * - `true`: every payload for the relationship MUST carry a
1052
+ * `links` object with a `related` link. `data` may be
1053
+ * omitted; when present, the referenced resource MUST be
1054
+ * included in the payload.
1055
+ * - `false` (default): whenever the relationship is present
1056
+ * in a payload its `data` member MUST be present and the
1057
+ * referenced resource MUST be included in the payload.
1058
+ * The relationship SHOULD NOT carry `links`.
1059
+ *
1060
+ * Related resources are never fetched automatically.
1038
1061
  *
1039
1062
  * @public
1040
1063
  */
@@ -1072,17 +1095,37 @@ interface ResourceField {
1072
1095
  }
1073
1096
  /**
1074
1097
  * Represents a field that is a reference to
1075
- * a collection of other resources, potentially
1076
- * paginate.
1077
- *
1078
- * SUPPORT FOR THIS FEATURE IS NOT YET IMPLEMENTED
1079
- * BY ReactiveResource. It is not yet part of
1080
- * {@link PolarisModeFieldSchema} or {@link LegacyModeFieldSchema},
1081
- * and reading or setting the field fails an assertion
1082
- * in development builds.
1098
+ * a collection of other resources.
1083
1099
  *
1084
- * @summary Field schema of kind `collection` for a possibly paginated reference to other resources; not yet implemented
1085
- * by `ReactiveResource`.
1100
+ * The value of a `collection` field on a ReactiveResource is a
1101
+ * `ReactiveRelationshipDocument` whose `data` is a reactive array
1102
+ * of the related resources, and whose `links` and `meta` mirror the
1103
+ * relationship payload received from the API.
1104
+ *
1105
+ * ```ts
1106
+ * const user = store.peekRecord<User>('user', '1');
1107
+ * user.friends.data; // User[] | undefined
1108
+ * user.friends.links; // { related: '/users/1/friends' }
1109
+ * ```
1110
+ *
1111
+ * The relationship payload for this field is expected to have the
1112
+ * shape `{ data?: { type, id }[], links?: Links, meta?: Meta }`.
1113
+ * When `data` is omitted from the payload `doc.data` is `undefined`
1114
+ * and `doc.fetch()` may be used to load the related resources via
1115
+ * the `related` link.
1116
+ *
1117
+ * Collection relationships are not paginated: pagination links present
1118
+ * on the relationship are surfaced on `doc.links` but are never merged
1119
+ * into the relationship's membership. Large, sortable, filterable or
1120
+ * paginated lists should be loaded with a top-level request instead.
1121
+ *
1122
+ * In LegacyMode the relationship is mutable via `doc.data.push(record)`
1123
+ * (and the other array mutation methods) or `doc.data = [records]`.
1124
+ * In PolarisMode it is immutable unless the parent resource has been
1125
+ * checked out for editing.
1126
+ *
1127
+ * @summary Field schema of kind `collection` for a reference to other resources, whose value is a
1128
+ * `ReactiveRelationshipDocument`.
1086
1129
  * @public
1087
1130
  */
1088
1131
  interface CollectionField {
@@ -1139,23 +1182,24 @@ interface CollectionField {
1139
1182
  */
1140
1183
  options?: {
1141
1184
  /**
1142
- * Whether the relationship is async
1185
+ * Whether the relationship is async.
1143
1186
  *
1144
- * If true, it is expected that the cache
1145
- * data for this field will contain links
1146
- * that can be used to fetch the related
1147
- * resources when needed.
1187
+ * For `collection` fields `async` describes what the API
1188
+ * sends for the relationship (see the Relationship
1189
+ * Specification in the manual):
1148
1190
  *
1149
- * When false, it is expected that all related
1150
- * resources are loaded together with this resource,
1151
- * and that the cache data for this field will
1152
- * contain the full list of pointers.
1191
+ * - `true`: every payload for the relationship MUST carry a
1192
+ * `links` object with a `related` link. `data` may be
1193
+ * omitted; when present, every referenced resource MUST be
1194
+ * included in the payload.
1195
+ * - `false` (default): whenever the relationship is present
1196
+ * in a payload its `data` member MUST be present (an array,
1197
+ * possibly empty) and every referenced resource MUST be
1198
+ * included in the payload. The relationship SHOULD NOT
1199
+ * carry `links`.
1153
1200
  *
1154
- * When true, it is expected that the relationship
1155
- * is paginated. If the relationship is not paginated,
1156
- * then the cache data for "page 1" would contain the
1157
- * full list of pointers, and loading "page 1" would
1158
- * load all related resources.
1201
+ * Related resources are never fetched automatically. Use
1202
+ * `doc.fetch()` or a top-level request to load them.
1159
1203
  *
1160
1204
  * @public
1161
1205
  */
@@ -1984,8 +2028,8 @@ interface LinksModeHasManyField {
1984
2028
  * - {@link ArrayField}
1985
2029
  * - {@link SchemaArrayField}
1986
2030
  * - {@link DerivedField}
1987
- * - {@link ResourceField | ResourceField (not yet implemented)}
1988
- * - {@link CollectionField | CollectionField (not yet implemented)}
2031
+ * - {@link ResourceField}
2032
+ * - {@link CollectionField}
1989
2033
  * - {@link LegacyAttributeField}
1990
2034
  * - {@link LegacyBelongsToField}
1991
2035
  * - {@link LegacyHasManyField}
@@ -1994,7 +2038,7 @@ interface LinksModeHasManyField {
1994
2038
  * and hasMany fields.
1995
2039
  * @public
1996
2040
  */
1997
- type LegacyModeFieldSchema = GenericField | LegacyAliasField | LocalField | ObjectField | SchemaObjectField | ArrayField | SchemaArrayField | DerivedField | LegacyAttributeField | LegacyBelongsToField | LegacyHasManyField;
2041
+ type LegacyModeFieldSchema = GenericField | LegacyAliasField | LocalField | ObjectField | SchemaObjectField | ArrayField | SchemaArrayField | DerivedField | ResourceField | CollectionField | LegacyAttributeField | LegacyBelongsToField | LegacyHasManyField;
1998
2042
  /**
1999
2043
  * A union of all possible PolarisMode field schemas.
2000
2044
  *
@@ -2008,8 +2052,8 @@ type LegacyModeFieldSchema = GenericField | LegacyAliasField | LocalField | Obje
2008
2052
  * - {@link ArrayField}
2009
2053
  * - {@link SchemaArrayField}
2010
2054
  * - {@link DerivedField}
2011
- * - {@link ResourceField | ResourceField (not yet implemented)}
2012
- * - {@link CollectionField | CollectionField (not yet implemented)}
2055
+ * - {@link ResourceField}
2056
+ * - {@link CollectionField}
2013
2057
  * - {@link LinksModeBelongsToField}
2014
2058
  * - {@link LinksModeHasManyField}
2015
2059
  *
@@ -2017,7 +2061,7 @@ type LegacyModeFieldSchema = GenericField | LegacyAliasField | LocalField | Obje
2017
2061
  * LinksMode forms.
2018
2062
  * @public
2019
2063
  */
2020
- type PolarisModeFieldSchema = GenericField | PolarisAliasField | LocalField | ObjectField | SchemaObjectField | ArrayField | SchemaArrayField | DerivedField | LinksModeBelongsToField | LinksModeHasManyField;
2064
+ type PolarisModeFieldSchema = GenericField | PolarisAliasField | LocalField | ObjectField | SchemaObjectField | ArrayField | SchemaArrayField | DerivedField | ResourceField | CollectionField | LinksModeBelongsToField | LinksModeHasManyField;
2021
2065
  /**
2022
2066
  * A union of all possible LegacyMode and PolarisMode
2023
2067
  * field schemas.
@@ -2406,6 +2450,26 @@ declare function objectSchema<T extends ObjectSchema>(schema: T): T;
2406
2450
  * `@id`.
2407
2451
  * @public
2408
2452
  */
2453
+ /**
2454
+ * Whether a field kind is a to-many relationship: the legacy `hasMany` or the
2455
+ * `collection` kind.
2456
+ *
2457
+ * @public
2458
+ */
2459
+ declare function isManyKind(kind: string): kind is "hasMany" | "collection";
2460
+ /**
2461
+ * Whether a field kind is a to-one relationship: the legacy `belongsTo` or the
2462
+ * `resource` kind.
2463
+ *
2464
+ * @public
2465
+ */
2466
+ declare function isSingleKind(kind: string): kind is "belongsTo" | "resource";
2467
+ /**
2468
+ * Whether a field kind is any relationship kind, legacy or not.
2469
+ *
2470
+ * @public
2471
+ */
2472
+ declare function isRelationshipKind(kind: string): kind is "belongsTo" | "hasMany" | "resource" | "collection";
2409
2473
  declare function isResourceSchema(schema: ResourceSchema | ObjectSchema): schema is ResourceSchema;
2410
2474
  /**
2411
2475
  * A type utility to narrow a schema to LegacyResourceSchema
@@ -2448,5 +2512,5 @@ type LegacyField = LegacyAttributeField | LegacyBelongsToField | LegacyHasManyFi
2448
2512
  * @public
2449
2513
  */
2450
2514
  type LegacyRelationshipField = LegacyBelongsToField | LegacyHasManyField | LinksModeBelongsToField | LinksModeHasManyField;
2451
- export { ResourceField as A, ObjectField as C, PolarisModeFieldSchema as D, PolarisAliasField as E, Trait as F, isLegacyResourceSchema as I, isResourceSchema as L, Schema as M, SchemaArrayField as N, PolarisResourceSchema as O, SchemaObjectField as P, objectSchema as R, ObjectAliasField as S, ObjectSchema as T, LegacyResourceSchema as _, DerivedField as a, LinksModeHasManyField as b, HashField as c, LegacyAttributeField as d, LegacyBelongsToField as f, LegacyRelationshipField as g, LegacyModeFieldSchema as h, CollectionField as i, ResourceSchema as j, PolarisTrait as k, IdentityField as l, LegacyHasManyField as m, AttrOptions as n, FieldSchema as o, LegacyField as p, CacheableFieldSchema as r, GenericField as s, ArrayField as t, LegacyAliasField as u, LegacyTrait as v, ObjectFieldSchema as w, LocalField as x, LinksModeBelongsToField as y, resourceSchema as z };
2452
- //# sourceMappingURL=fields-r1rZJB9d.d.ts.map
2515
+ export { ResourceField as A, isSingleKind as B, ObjectField as C, PolarisModeFieldSchema as D, PolarisAliasField as E, Trait as F, resourceSchema as H, isLegacyResourceSchema as I, isManyKind as L, Schema as M, SchemaArrayField as N, PolarisResourceSchema as O, SchemaObjectField as P, isRelationshipKind as R, ObjectAliasField as S, ObjectSchema as T, objectSchema as V, LegacyResourceSchema as _, DerivedField as a, LinksModeHasManyField as b, HashField as c, LegacyAttributeField as d, LegacyBelongsToField as f, LegacyRelationshipField as g, LegacyModeFieldSchema as h, CollectionField as i, ResourceSchema as j, PolarisTrait as k, IdentityField as l, LegacyHasManyField as m, AttrOptions as n, FieldSchema as o, LegacyField as p, CacheableFieldSchema as r, GenericField as s, ArrayField as t, LegacyAliasField as u, LegacyTrait as v, ObjectFieldSchema as w, LocalField as x, LinksModeBelongsToField as y, isResourceSchema as z };
2516
+ //# sourceMappingURL=fields-B-jO-dzB.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fields-B-jO-dzB.d.ts","names":[],"sources":["../src/types/schema/fields.ts"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { Gt as GraphEdge, Ht as peekGraph, Jt as CollectionEdge, Kt as ResourceEdge, Ut as isBelongsTo, Vt as graphFor, Wt as Graph, Yt as UpgradedMeta, qt as ImplicitEdge } from "../internal-D_WIXC4r.js";
1
+ import { Gt as GraphEdge, Ht as peekGraph, Jt as CollectionEdge, Kt as ResourceEdge, Ut as isBelongsTo, Vt as graphFor, Wt as Graph, Yt as UpgradedMeta, qt as ImplicitEdge } from "../internal-BrC3kM86.js";
2
2
  export { type CollectionEdge, type Graph, type GraphEdge, type ImplicitEdge, type ResourceEdge, type UpgradedMeta, graphFor, isBelongsTo, peekGraph };
@@ -1,4 +1,5 @@
1
1
  import { getOrSetGlobal, peekTransient, setTransient } from "../types/-private.js";
2
+ import { isRelationshipKind } from "../types/schema/fields.js";
2
3
  import { getGlobalConfig, macroCondition } from "@embroider/macros";
3
4
  import { deprecate, warn } from "@ember/debug";
4
5
 
@@ -190,20 +191,14 @@ function assertRelationshipData(store, resourceKey, data, meta) {
190
191
  }
191
192
 
192
193
  // src/graph/-private/-edge-definition.ts
193
- const RELATIONSHIP_KINDS = [
194
- "belongsTo",
195
- "hasMany",
196
- "resource",
197
- "collection"
198
- ];
199
194
  function isLegacyField(field) {
200
195
  return field.kind === "belongsTo" || field.kind === "hasMany";
201
196
  }
202
197
  function isRelationshipField(field) {
203
- return RELATIONSHIP_KINDS.includes(field.kind);
198
+ return isRelationshipKind(field.kind);
204
199
  }
205
200
  function temporaryConvertToLegacy(field) {
206
- return {
201
+ const legacy = {
207
202
  kind: field.kind === "resource" ? "belongsTo" : "hasMany",
208
203
  name: field.name,
209
204
  type: field.type,
@@ -213,6 +208,8 @@ function temporaryConvertToLegacy(field) {
213
208
  resetOnRemoteUpdate: false
214
209
  }, field.options)
215
210
  };
211
+ if (field.sourceKey) legacy.sourceKey = field.sourceKey;
212
+ return legacy;
216
213
  }
217
214
  /**
218
215
  *
@@ -297,10 +294,12 @@ function syncMeta(definition, inverseDefinition) {
297
294
  inverseDefinition.resetOnRemoteUpdate = resetOnRemoteUpdate;
298
295
  }
299
296
  function upgradeMeta(meta) {
297
+ const fieldKind = meta.kind;
300
298
  if (!isLegacyField(meta)) meta = temporaryConvertToLegacy(meta);
301
299
  const niceMeta = {};
302
300
  const options = meta.options;
303
301
  niceMeta.kind = meta.kind;
302
+ niceMeta.fieldKind = fieldKind;
304
303
  niceMeta.key = meta.sourceKey ?? meta.name;
305
304
  niceMeta.name = meta.name;
306
305
  niceMeta.type = meta.type;
@@ -389,7 +388,7 @@ function upgradeDefinition(graph, key, propertyName, isImplicit = false) {
389
388
  })(storeWrapper.schema.hasResource({ type: inverseType }));
390
389
  inverseDefinition = null;
391
390
  } else {
392
- inverseKey = inverseForRelationship(getStore(storeWrapper), key, meta.name);
391
+ inverseKey = inverseNameFor(meta);
393
392
  if (!inverseKey && definition.isPolymorphic && definition.inverseKey) inverseDefinition = {
394
393
  kind: "belongsTo",
395
394
  key: definition.inverseKey,
@@ -413,10 +412,13 @@ function upgradeDefinition(graph, key, propertyName, isImplicit = false) {
413
412
  macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) && ((test) => {
414
413
  if (!test) throw new Error(`Expected ${inverseKey} to be a relationship`);
415
414
  })(isRelationshipField(metaFromInverse));
415
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) && ((test) => {
416
+ if (!test) throw new Error(`'${type}.${propertyName}' is a '${meta.kind}' field, but its inverse '${inverseType}.${inverseKey}' is a '${metaFromInverse.kind}' field. A 'resource' or 'collection' field can only have a 'resource' or 'collection' field as its inverse, and a 'belongsTo' or 'hasMany' field can only have a 'belongsTo' or 'hasMany' field as its inverse.`);
417
+ })(isLegacyField(meta) === isLegacyField(metaFromInverse));
416
418
  inverseDefinition = upgradeMeta(metaFromInverse);
417
- inverseKey = inverseDefinition.key;
418
419
  }
419
420
  }
421
+ if (inverseDefinition) inverseKey = inverseDefinition.key;
420
422
  if (!inverseDefinition) {
421
423
  inverseKey = implicitKeyFor(type, propertyName);
422
424
  inverseDefinition = {
@@ -497,16 +499,20 @@ function upgradeDefinition(graph, key, propertyName, isImplicit = false) {
497
499
  expandingSet(cache, inverseType, inverseKey, info);
498
500
  return info;
499
501
  }
500
- function inverseForRelationship(store, resourceKey, key) {
501
- const definition = store.schema.fields(resourceKey).get(key);
502
- if (!definition) return null;
503
- macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) && ((test) => {
504
- if (!test) throw new Error(`Expected ${key} to be a relationship`);
505
- })(isRelationshipField(definition));
502
+ /**
503
+ * The `name` of the field on the related type that `field` declares as its inverse,
504
+ * or `null` when it declares no inverse.
505
+ *
506
+ * `options.inverse` always names the inverse by its `name`, never by its `sourceKey`.
507
+ * `resource` and `collection` fields may omit it, in which case they are unidirectional;
508
+ * the legacy kinds must state it explicitly.
509
+ */
510
+ function inverseNameFor(field) {
511
+ const { options } = isLegacyField(field) ? field : temporaryConvertToLegacy(field);
506
512
  macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) && ((test) => {
507
513
  if (!test) throw new Error(`Expected the relationship defintion to specify the inverse type or null.`);
508
- })(definition.options?.inverse === null || typeof definition.options?.inverse === "string" && definition.options.inverse.length > 0);
509
- return definition.options.inverse;
514
+ })(options?.inverse === null || typeof options?.inverse === "string" && options.inverse.length > 0);
515
+ return options.inverse;
510
516
  }
511
517
 
512
518
  // src/graph/-private/debug/assert-polymorphic-type.ts
@@ -577,6 +583,7 @@ if (macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG)) {
577
583
  name: definition.inverseName,
578
584
  type: definition.inverseType,
579
585
  kind: definition.inverseKind,
586
+ fieldKind: definition.inverseKind,
580
587
  isAsync: definition.inverseIsAsync,
581
588
  isPolymorphic: true,
582
589
  isLinksMode: definition.isLinksMode,
@@ -802,6 +809,7 @@ function addToInverse(graph, resourceKey, key, value, isRemote) {
802
809
  graph._addToTransaction(relationship);
803
810
  if (relationship.remoteState !== null) removeFromInverse(graph, relationship.remoteState, relationship.definition.inverseKey, resourceKey, isRemote);
804
811
  relationship.remoteState = value;
812
+ relationship.state.hasReceivedRemoteData = true;
805
813
  notifyChange(graph, relationship);
806
814
  }
807
815
  if (relationship.localState !== value) {
@@ -815,8 +823,10 @@ function addToInverse(graph, resourceKey, key, value, isRemote) {
815
823
  graph._addToTransaction(relationship);
816
824
  relationship.remoteState.push(value);
817
825
  relationship.remoteMembers.add(value);
818
- if (relationship.additions?.has(value)) relationship.additions.delete(value);
819
- else {
826
+ if (relationship.additions?.has(value)) {
827
+ relationship.additions.delete(value);
828
+ flushCanonical(graph, relationship, "remote");
829
+ } else {
820
830
  relationship.isDirty = true;
821
831
  relationship.state.hasReceivedData = true;
822
832
  flushCanonical(graph, relationship);
@@ -844,6 +854,7 @@ function removeFromInverse(graph, resourceKey, key, value, isRemote) {
844
854
  if (isRemote) {
845
855
  graph._addToTransaction(relationship);
846
856
  relationship.remoteState = null;
857
+ relationship.state.hasReceivedRemoteData = true;
847
858
  notifyChange(graph, relationship);
848
859
  }
849
860
  if (relationship.localState === value) {
@@ -853,7 +864,9 @@ function removeFromInverse(graph, resourceKey, key, value, isRemote) {
853
864
  } else if (isHasMany(relationship)) {
854
865
  if (isRemote) {
855
866
  graph._addToTransaction(relationship);
867
+ const wasMember = relationship.remoteMembers.has(value);
856
868
  if (_removeRemote(relationship, value)) notifyChange(graph, relationship);
869
+ else if (wasMember) notifyChange(graph, relationship, "remote");
857
870
  } else if (_removeLocal(relationship, value)) notifyChange(graph, relationship, "local");
858
871
  } else if (isRemote) {
859
872
  relationship.remoteMembers.delete(value);