@warp-drive/core 5.8.0-alpha.30 → 5.8.0-alpha.34

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 (707) hide show
  1. package/declarations/index.d.ts +9 -2
  2. package/declarations/store/-private/caches/instance-cache.d.ts +1 -1
  3. package/declarations/store/deprecated/-private.d.ts +1 -1
  4. package/declarations/types/schema/fields.d.ts +3 -3
  5. package/declarations/types/schema/schema-service.d.ts +4 -4
  6. package/dist/{index-CHrZ1B2X.js → index-D4si_DxB.js} +19 -9
  7. package/dist/index.js +1 -1
  8. package/dist/reactive.js +1 -1
  9. package/dist/store/-private.js +1 -1
  10. package/dist/types/-private.js +1 -1
  11. package/dist/unpkg/dev/build-config/babel-macros.js +1 -0
  12. package/dist/unpkg/dev/build-config/canary-features.js +1 -0
  13. package/dist/unpkg/dev/build-config/debugging.js +1 -0
  14. package/dist/unpkg/dev/build-config/deprecations.js +1 -0
  15. package/dist/unpkg/dev/build-config/env.js +1 -0
  16. package/dist/unpkg/dev/build-config/macros.js +1 -0
  17. package/dist/unpkg/dev/build-config.js +1 -0
  18. package/dist/unpkg/dev/configure-C3x8YXzL.js +181 -0
  19. package/dist/unpkg/dev/configure.js +1 -0
  20. package/dist/unpkg/dev/declarations/build-config/babel-macros.d.ts +1 -0
  21. package/dist/unpkg/dev/declarations/build-config/canary-features.d.ts +1 -0
  22. package/dist/unpkg/dev/declarations/build-config/debugging.d.ts +1 -0
  23. package/dist/unpkg/dev/declarations/build-config/deprecations.d.ts +1 -0
  24. package/dist/unpkg/dev/declarations/build-config/env.d.ts +1 -0
  25. package/dist/unpkg/dev/declarations/build-config/macros.d.ts +1 -0
  26. package/dist/unpkg/dev/declarations/build-config.d.ts +18 -0
  27. package/dist/unpkg/dev/declarations/configure.d.ts +7 -0
  28. package/dist/unpkg/dev/declarations/graph/-private/-diff.d.ts +19 -0
  29. package/dist/unpkg/dev/declarations/graph/-private/-edge-definition.d.ts +149 -0
  30. package/dist/unpkg/dev/declarations/graph/-private/-state.d.ts +9 -0
  31. package/dist/unpkg/dev/declarations/graph/-private/-utils.d.ts +25 -0
  32. package/dist/unpkg/dev/declarations/graph/-private/coerce-id.d.ts +4 -0
  33. package/dist/unpkg/dev/declarations/graph/-private/debug/assert-polymorphic-type.d.ts +6 -0
  34. package/dist/unpkg/dev/declarations/graph/-private/edges/collection.d.ts +39 -0
  35. package/dist/unpkg/dev/declarations/graph/-private/edges/implicit.d.ts +43 -0
  36. package/dist/unpkg/dev/declarations/graph/-private/edges/resource.d.ts +23 -0
  37. package/dist/unpkg/dev/declarations/graph/-private/graph.d.ts +56 -0
  38. package/dist/unpkg/dev/declarations/graph/-private/normalize-link.d.ts +2 -0
  39. package/dist/unpkg/dev/declarations/graph/-private/operations/add-to-related-records.d.ts +4 -0
  40. package/dist/unpkg/dev/declarations/graph/-private/operations/merge-identifier.d.ts +3 -0
  41. package/dist/unpkg/dev/declarations/graph/-private/operations/remove-from-related-records.d.ts +4 -0
  42. package/dist/unpkg/dev/declarations/graph/-private/operations/replace-related-record.d.ts +3 -0
  43. package/dist/unpkg/dev/declarations/graph/-private/operations/replace-related-records.d.ts +7 -0
  44. package/dist/unpkg/dev/declarations/graph/-private/operations/update-relationship.d.ts +9 -0
  45. package/dist/unpkg/dev/declarations/graph/-private.d.ts +13 -0
  46. package/dist/unpkg/dev/declarations/index.d.ts +100 -0
  47. package/dist/unpkg/dev/declarations/reactive/-private/default-mode.d.ts +73 -0
  48. package/dist/unpkg/dev/declarations/reactive/-private/document.d.ts +142 -0
  49. package/dist/unpkg/dev/declarations/reactive/-private/fields/extension.d.ts +8 -0
  50. package/dist/unpkg/dev/declarations/reactive/-private/fields/get-field-key.d.ts +8 -0
  51. package/dist/unpkg/dev/declarations/reactive/-private/fields/managed-array.d.ts +18 -0
  52. package/dist/unpkg/dev/declarations/reactive/-private/fields/managed-object.d.ts +17 -0
  53. package/dist/unpkg/dev/declarations/reactive/-private/fields/many-array-manager.d.ts +19 -0
  54. package/dist/unpkg/dev/declarations/reactive/-private/hooks.d.ts +5 -0
  55. package/dist/unpkg/dev/declarations/reactive/-private/kind/alias-field.d.ts +4 -0
  56. package/dist/unpkg/dev/declarations/reactive/-private/kind/array-field.d.ts +4 -0
  57. package/dist/unpkg/dev/declarations/reactive/-private/kind/attribute-field.d.ts +4 -0
  58. package/dist/unpkg/dev/declarations/reactive/-private/kind/belongs-to-field.d.ts +4 -0
  59. package/dist/unpkg/dev/declarations/reactive/-private/kind/collection-field.d.ts +4 -0
  60. package/dist/unpkg/dev/declarations/reactive/-private/kind/derived-field.d.ts +4 -0
  61. package/dist/unpkg/dev/declarations/reactive/-private/kind/generic-field.d.ts +4 -0
  62. package/dist/unpkg/dev/declarations/reactive/-private/kind/has-many-field.d.ts +4 -0
  63. package/dist/unpkg/dev/declarations/reactive/-private/kind/hash-field.d.ts +4 -0
  64. package/dist/unpkg/dev/declarations/reactive/-private/kind/identity-field.d.ts +4 -0
  65. package/dist/unpkg/dev/declarations/reactive/-private/kind/local-field.d.ts +4 -0
  66. package/dist/unpkg/dev/declarations/reactive/-private/kind/object-field.d.ts +4 -0
  67. package/dist/unpkg/dev/declarations/reactive/-private/kind/resource-field.d.ts +4 -0
  68. package/dist/unpkg/dev/declarations/reactive/-private/kind/schema-array-field.d.ts +4 -0
  69. package/dist/unpkg/dev/declarations/reactive/-private/kind/schema-object-field.d.ts +4 -0
  70. package/dist/unpkg/dev/declarations/reactive/-private/record.d.ts +83 -0
  71. package/dist/unpkg/dev/declarations/reactive/-private/schema.d.ts +326 -0
  72. package/dist/unpkg/dev/declarations/reactive/-private/symbols.d.ts +5 -0
  73. package/dist/unpkg/dev/declarations/reactive/-private.d.ts +2 -0
  74. package/dist/unpkg/dev/declarations/reactive.d.ts +287 -0
  75. package/dist/unpkg/dev/declarations/request/-private/context.d.ts +39 -0
  76. package/dist/unpkg/dev/declarations/request/-private/debug.d.ts +4 -0
  77. package/dist/unpkg/dev/declarations/request/-private/fetch.d.ts +33 -0
  78. package/dist/unpkg/dev/declarations/request/-private/future.d.ts +7 -0
  79. package/dist/unpkg/dev/declarations/request/-private/manager.d.ts +158 -0
  80. package/dist/unpkg/dev/declarations/request/-private/promise-cache.d.ts +28 -0
  81. package/dist/unpkg/dev/declarations/request/-private/types.d.ts +234 -0
  82. package/dist/unpkg/dev/declarations/request/-private/utils.d.ts +57 -0
  83. package/dist/unpkg/dev/declarations/request.d.ts +52 -0
  84. package/dist/unpkg/dev/declarations/store/-private/cache-handler/handler.d.ts +56 -0
  85. package/dist/unpkg/dev/declarations/store/-private/cache-handler/types.d.ts +98 -0
  86. package/dist/unpkg/dev/declarations/store/-private/cache-handler/utils.d.ts +31 -0
  87. package/dist/unpkg/dev/declarations/store/-private/caches/instance-cache.d.ts +58 -0
  88. package/dist/unpkg/dev/declarations/store/-private/caches/resource-utils.d.ts +9 -0
  89. package/dist/unpkg/dev/declarations/store/-private/debug/utils.d.ts +7 -0
  90. package/dist/unpkg/dev/declarations/store/-private/default-cache-policy.d.ts +387 -0
  91. package/dist/unpkg/dev/declarations/store/-private/managers/cache-capabilities-manager.d.ts +34 -0
  92. package/dist/unpkg/dev/declarations/store/-private/managers/cache-key-manager.d.ts +304 -0
  93. package/dist/unpkg/dev/declarations/store/-private/managers/cache-manager.d.ts +380 -0
  94. package/dist/unpkg/dev/declarations/store/-private/managers/notification-manager.d.ts +83 -0
  95. package/dist/unpkg/dev/declarations/store/-private/managers/record-array-manager.d.ts +100 -0
  96. package/dist/unpkg/dev/declarations/store/-private/network/request-cache.d.ts +103 -0
  97. package/dist/unpkg/dev/declarations/store/-private/new-core-tmp/expensive-subscription.d.ts +24 -0
  98. package/dist/unpkg/dev/declarations/store/-private/new-core-tmp/promise-state.d.ts +264 -0
  99. package/dist/unpkg/dev/declarations/store/-private/new-core-tmp/reactivity/configure.d.ts +138 -0
  100. package/dist/unpkg/dev/declarations/store/-private/new-core-tmp/reactivity/internal.d.ts +154 -0
  101. package/dist/unpkg/dev/declarations/store/-private/new-core-tmp/reactivity/signal.d.ts +56 -0
  102. package/dist/unpkg/dev/declarations/store/-private/new-core-tmp/request-state.d.ts +372 -0
  103. package/dist/unpkg/dev/declarations/store/-private/new-core-tmp/request-subscription.d.ts +177 -0
  104. package/dist/unpkg/dev/declarations/store/-private/record-arrays/-utils.d.ts +80 -0
  105. package/dist/unpkg/dev/declarations/store/-private/record-arrays/legacy-live-array.d.ts +81 -0
  106. package/dist/unpkg/dev/declarations/store/-private/record-arrays/legacy-many-array.d.ts +133 -0
  107. package/dist/unpkg/dev/declarations/store/-private/record-arrays/legacy-query.d.ts +81 -0
  108. package/dist/unpkg/dev/declarations/store/-private/record-arrays/native-proxy-type-fix.d.ts +3 -0
  109. package/dist/unpkg/dev/declarations/store/-private/record-arrays/resource-array.d.ts +67 -0
  110. package/dist/unpkg/dev/declarations/store/-private/store-service.d.ts +874 -0
  111. package/dist/unpkg/dev/declarations/store/-private/utils/coerce-id.d.ts +4 -0
  112. package/dist/unpkg/dev/declarations/store/-private/utils/construct-resource.d.ts +6 -0
  113. package/dist/unpkg/dev/declarations/store/-private/utils/is-non-empty-string.d.ts +1 -0
  114. package/dist/unpkg/dev/declarations/store/-private/utils/normalize-model-name.d.ts +1 -0
  115. package/dist/unpkg/dev/declarations/store/-private/utils/uuid-polyfill.d.ts +1 -0
  116. package/dist/unpkg/dev/declarations/store/-private.d.ts +29 -0
  117. package/dist/unpkg/dev/declarations/store/-types/q/cache-capabilities-manager.d.ts +90 -0
  118. package/dist/unpkg/dev/declarations/store/-types/q/identifier.d.ts +23 -0
  119. package/dist/unpkg/dev/declarations/store/-types/q/record-instance.d.ts +22 -0
  120. package/dist/unpkg/dev/declarations/store/-types/q/store.d.ts +31 -0
  121. package/dist/unpkg/dev/declarations/store/deprecated/-private.d.ts +223 -0
  122. package/dist/unpkg/dev/declarations/store/deprecated/store.d.ts +784 -0
  123. package/dist/unpkg/dev/declarations/store.d.ts +2 -0
  124. package/dist/unpkg/dev/declarations/types/-private.d.ts +22 -0
  125. package/dist/unpkg/dev/declarations/types/cache/aliases.d.ts +1 -0
  126. package/dist/unpkg/dev/declarations/types/cache/change.d.ts +6 -0
  127. package/dist/unpkg/dev/declarations/types/cache/mutations.d.ts +38 -0
  128. package/dist/unpkg/dev/declarations/types/cache/operations.d.ts +168 -0
  129. package/dist/unpkg/dev/declarations/types/cache/relationship.d.ts +13 -0
  130. package/dist/unpkg/dev/declarations/types/cache.d.ts +429 -0
  131. package/dist/unpkg/dev/declarations/types/graph.d.ts +47 -0
  132. package/dist/unpkg/dev/declarations/types/identifier.d.ts +86 -0
  133. package/dist/unpkg/dev/declarations/types/json/raw.d.ts +6 -0
  134. package/dist/unpkg/dev/declarations/types/params.d.ts +8 -0
  135. package/dist/unpkg/dev/declarations/types/record.d.ts +269 -0
  136. package/dist/unpkg/dev/declarations/types/request.d.ts +367 -0
  137. package/dist/unpkg/dev/declarations/types/runtime.d.ts +14 -0
  138. package/dist/unpkg/dev/declarations/types/schema/concepts.d.ts +23 -0
  139. package/dist/unpkg/dev/declarations/types/schema/fields.d.ts +2200 -0
  140. package/dist/unpkg/dev/declarations/types/schema/fields.type-test.d.ts +1 -0
  141. package/dist/unpkg/dev/declarations/types/schema/schema-service.d.ts +380 -0
  142. package/dist/unpkg/dev/declarations/types/spec/document.d.ts +67 -0
  143. package/dist/unpkg/dev/declarations/types/spec/error.d.ts +18 -0
  144. package/dist/unpkg/dev/declarations/types/spec/json-api-raw.d.ts +139 -0
  145. package/dist/unpkg/dev/declarations/types/symbols.d.ts +78 -0
  146. package/dist/unpkg/dev/declarations/types/utils.d.ts +5 -0
  147. package/dist/unpkg/dev/declarations/types.d.ts +11 -0
  148. package/dist/unpkg/dev/declarations/utils/string.d.ts +47 -0
  149. package/dist/unpkg/dev/default-cache-policy-D7_u4YRH.js +572 -0
  150. package/dist/unpkg/dev/graph/-private.js +3374 -0
  151. package/dist/unpkg/dev/index-D4si_DxB.js +11746 -0
  152. package/dist/unpkg/dev/index.js +8 -0
  153. package/dist/unpkg/dev/reactive/-private.js +1 -0
  154. package/dist/unpkg/dev/reactive.js +129 -0
  155. package/dist/unpkg/dev/request-oqoLC9rz.js +725 -0
  156. package/dist/unpkg/dev/request.js +1 -0
  157. package/dist/unpkg/dev/store/-private.js +2 -0
  158. package/dist/unpkg/dev/store.js +1 -0
  159. package/dist/unpkg/dev/symbols-sql1_mdx.js +39 -0
  160. package/dist/unpkg/dev/types/-private.js +79 -0
  161. package/dist/unpkg/dev/types/cache/aliases.js +0 -0
  162. package/dist/unpkg/dev/types/cache/change.js +0 -0
  163. package/dist/unpkg/dev/types/cache/mutations.js +0 -0
  164. package/dist/unpkg/dev/types/cache/operations.js +0 -0
  165. package/dist/unpkg/dev/types/cache/relationship.js +0 -0
  166. package/dist/unpkg/dev/types/cache.js +0 -0
  167. package/dist/unpkg/dev/types/graph.js +0 -0
  168. package/dist/unpkg/dev/types/identifier.js +63 -0
  169. package/dist/unpkg/dev/types/json/raw.js +0 -0
  170. package/dist/unpkg/dev/types/params.js +0 -0
  171. package/dist/unpkg/dev/types/record.js +191 -0
  172. package/dist/unpkg/dev/types/request.js +77 -0
  173. package/dist/unpkg/dev/types/runtime.js +34 -0
  174. package/dist/unpkg/dev/types/schema/concepts.js +0 -0
  175. package/dist/unpkg/dev/types/schema/fields.js +505 -0
  176. package/dist/unpkg/dev/types/schema/fields.type-test.js +0 -0
  177. package/dist/unpkg/dev/types/schema/schema-service.js +0 -0
  178. package/dist/unpkg/dev/types/spec/document.js +0 -0
  179. package/dist/unpkg/dev/types/spec/error.js +0 -0
  180. package/dist/unpkg/dev/types/spec/json-api-raw.js +0 -0
  181. package/dist/unpkg/dev/types/symbols.js +84 -0
  182. package/dist/unpkg/dev/types/utils.js +0 -0
  183. package/dist/unpkg/dev/types.js +0 -0
  184. package/dist/unpkg/dev/utils/string.js +92 -0
  185. package/dist/unpkg/dev-deprecated/build-config/babel-macros.js +1 -0
  186. package/dist/unpkg/dev-deprecated/build-config/canary-features.js +1 -0
  187. package/dist/unpkg/dev-deprecated/build-config/debugging.js +1 -0
  188. package/dist/unpkg/dev-deprecated/build-config/deprecations.js +1 -0
  189. package/dist/unpkg/dev-deprecated/build-config/env.js +1 -0
  190. package/dist/unpkg/dev-deprecated/build-config/macros.js +1 -0
  191. package/dist/unpkg/dev-deprecated/build-config.js +1 -0
  192. package/dist/unpkg/dev-deprecated/configure-C3x8YXzL.js +181 -0
  193. package/dist/unpkg/dev-deprecated/configure.js +1 -0
  194. package/dist/unpkg/dev-deprecated/declarations/build-config/babel-macros.d.ts +1 -0
  195. package/dist/unpkg/dev-deprecated/declarations/build-config/canary-features.d.ts +1 -0
  196. package/dist/unpkg/dev-deprecated/declarations/build-config/debugging.d.ts +1 -0
  197. package/dist/unpkg/dev-deprecated/declarations/build-config/deprecations.d.ts +1 -0
  198. package/dist/unpkg/dev-deprecated/declarations/build-config/env.d.ts +1 -0
  199. package/dist/unpkg/dev-deprecated/declarations/build-config/macros.d.ts +1 -0
  200. package/dist/unpkg/dev-deprecated/declarations/build-config.d.ts +18 -0
  201. package/dist/unpkg/dev-deprecated/declarations/configure.d.ts +7 -0
  202. package/dist/unpkg/dev-deprecated/declarations/graph/-private/-diff.d.ts +19 -0
  203. package/dist/unpkg/dev-deprecated/declarations/graph/-private/-edge-definition.d.ts +149 -0
  204. package/dist/unpkg/dev-deprecated/declarations/graph/-private/-state.d.ts +9 -0
  205. package/dist/unpkg/dev-deprecated/declarations/graph/-private/-utils.d.ts +25 -0
  206. package/dist/unpkg/dev-deprecated/declarations/graph/-private/coerce-id.d.ts +4 -0
  207. package/dist/unpkg/dev-deprecated/declarations/graph/-private/debug/assert-polymorphic-type.d.ts +6 -0
  208. package/dist/unpkg/dev-deprecated/declarations/graph/-private/edges/collection.d.ts +39 -0
  209. package/dist/unpkg/dev-deprecated/declarations/graph/-private/edges/implicit.d.ts +43 -0
  210. package/dist/unpkg/dev-deprecated/declarations/graph/-private/edges/resource.d.ts +23 -0
  211. package/dist/unpkg/dev-deprecated/declarations/graph/-private/graph.d.ts +56 -0
  212. package/dist/unpkg/dev-deprecated/declarations/graph/-private/normalize-link.d.ts +2 -0
  213. package/dist/unpkg/dev-deprecated/declarations/graph/-private/operations/add-to-related-records.d.ts +4 -0
  214. package/dist/unpkg/dev-deprecated/declarations/graph/-private/operations/merge-identifier.d.ts +3 -0
  215. package/dist/unpkg/dev-deprecated/declarations/graph/-private/operations/remove-from-related-records.d.ts +4 -0
  216. package/dist/unpkg/dev-deprecated/declarations/graph/-private/operations/replace-related-record.d.ts +3 -0
  217. package/dist/unpkg/dev-deprecated/declarations/graph/-private/operations/replace-related-records.d.ts +7 -0
  218. package/dist/unpkg/dev-deprecated/declarations/graph/-private/operations/update-relationship.d.ts +9 -0
  219. package/dist/unpkg/dev-deprecated/declarations/graph/-private.d.ts +13 -0
  220. package/dist/unpkg/dev-deprecated/declarations/index.d.ts +100 -0
  221. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/default-mode.d.ts +73 -0
  222. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/document.d.ts +142 -0
  223. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/fields/extension.d.ts +8 -0
  224. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/fields/get-field-key.d.ts +8 -0
  225. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/fields/managed-array.d.ts +18 -0
  226. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/fields/managed-object.d.ts +17 -0
  227. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/fields/many-array-manager.d.ts +19 -0
  228. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/hooks.d.ts +5 -0
  229. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/kind/alias-field.d.ts +4 -0
  230. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/kind/array-field.d.ts +4 -0
  231. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/kind/attribute-field.d.ts +4 -0
  232. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/kind/belongs-to-field.d.ts +4 -0
  233. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/kind/collection-field.d.ts +4 -0
  234. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/kind/derived-field.d.ts +4 -0
  235. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/kind/generic-field.d.ts +4 -0
  236. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/kind/has-many-field.d.ts +4 -0
  237. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/kind/hash-field.d.ts +4 -0
  238. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/kind/identity-field.d.ts +4 -0
  239. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/kind/local-field.d.ts +4 -0
  240. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/kind/object-field.d.ts +4 -0
  241. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/kind/resource-field.d.ts +4 -0
  242. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/kind/schema-array-field.d.ts +4 -0
  243. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/kind/schema-object-field.d.ts +4 -0
  244. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/record.d.ts +83 -0
  245. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/schema.d.ts +326 -0
  246. package/dist/unpkg/dev-deprecated/declarations/reactive/-private/symbols.d.ts +5 -0
  247. package/dist/unpkg/dev-deprecated/declarations/reactive/-private.d.ts +2 -0
  248. package/dist/unpkg/dev-deprecated/declarations/reactive.d.ts +287 -0
  249. package/dist/unpkg/dev-deprecated/declarations/request/-private/context.d.ts +39 -0
  250. package/dist/unpkg/dev-deprecated/declarations/request/-private/debug.d.ts +4 -0
  251. package/dist/unpkg/dev-deprecated/declarations/request/-private/fetch.d.ts +33 -0
  252. package/dist/unpkg/dev-deprecated/declarations/request/-private/future.d.ts +7 -0
  253. package/dist/unpkg/dev-deprecated/declarations/request/-private/manager.d.ts +158 -0
  254. package/dist/unpkg/dev-deprecated/declarations/request/-private/promise-cache.d.ts +28 -0
  255. package/dist/unpkg/dev-deprecated/declarations/request/-private/types.d.ts +234 -0
  256. package/dist/unpkg/dev-deprecated/declarations/request/-private/utils.d.ts +57 -0
  257. package/dist/unpkg/dev-deprecated/declarations/request.d.ts +52 -0
  258. package/dist/unpkg/dev-deprecated/declarations/store/-private/cache-handler/handler.d.ts +56 -0
  259. package/dist/unpkg/dev-deprecated/declarations/store/-private/cache-handler/types.d.ts +98 -0
  260. package/dist/unpkg/dev-deprecated/declarations/store/-private/cache-handler/utils.d.ts +31 -0
  261. package/dist/unpkg/dev-deprecated/declarations/store/-private/caches/instance-cache.d.ts +58 -0
  262. package/dist/unpkg/dev-deprecated/declarations/store/-private/caches/resource-utils.d.ts +9 -0
  263. package/dist/unpkg/dev-deprecated/declarations/store/-private/debug/utils.d.ts +7 -0
  264. package/dist/unpkg/dev-deprecated/declarations/store/-private/default-cache-policy.d.ts +387 -0
  265. package/dist/unpkg/dev-deprecated/declarations/store/-private/managers/cache-capabilities-manager.d.ts +34 -0
  266. package/dist/unpkg/dev-deprecated/declarations/store/-private/managers/cache-key-manager.d.ts +304 -0
  267. package/dist/unpkg/dev-deprecated/declarations/store/-private/managers/cache-manager.d.ts +380 -0
  268. package/dist/unpkg/dev-deprecated/declarations/store/-private/managers/notification-manager.d.ts +83 -0
  269. package/dist/unpkg/dev-deprecated/declarations/store/-private/managers/record-array-manager.d.ts +100 -0
  270. package/dist/unpkg/dev-deprecated/declarations/store/-private/network/request-cache.d.ts +103 -0
  271. package/dist/unpkg/dev-deprecated/declarations/store/-private/new-core-tmp/expensive-subscription.d.ts +24 -0
  272. package/dist/unpkg/dev-deprecated/declarations/store/-private/new-core-tmp/promise-state.d.ts +264 -0
  273. package/dist/unpkg/dev-deprecated/declarations/store/-private/new-core-tmp/reactivity/configure.d.ts +138 -0
  274. package/dist/unpkg/dev-deprecated/declarations/store/-private/new-core-tmp/reactivity/internal.d.ts +154 -0
  275. package/dist/unpkg/dev-deprecated/declarations/store/-private/new-core-tmp/reactivity/signal.d.ts +56 -0
  276. package/dist/unpkg/dev-deprecated/declarations/store/-private/new-core-tmp/request-state.d.ts +372 -0
  277. package/dist/unpkg/dev-deprecated/declarations/store/-private/new-core-tmp/request-subscription.d.ts +177 -0
  278. package/dist/unpkg/dev-deprecated/declarations/store/-private/record-arrays/-utils.d.ts +80 -0
  279. package/dist/unpkg/dev-deprecated/declarations/store/-private/record-arrays/legacy-live-array.d.ts +81 -0
  280. package/dist/unpkg/dev-deprecated/declarations/store/-private/record-arrays/legacy-many-array.d.ts +133 -0
  281. package/dist/unpkg/dev-deprecated/declarations/store/-private/record-arrays/legacy-query.d.ts +81 -0
  282. package/dist/unpkg/dev-deprecated/declarations/store/-private/record-arrays/native-proxy-type-fix.d.ts +3 -0
  283. package/dist/unpkg/dev-deprecated/declarations/store/-private/record-arrays/resource-array.d.ts +67 -0
  284. package/dist/unpkg/dev-deprecated/declarations/store/-private/store-service.d.ts +874 -0
  285. package/dist/unpkg/dev-deprecated/declarations/store/-private/utils/coerce-id.d.ts +4 -0
  286. package/dist/unpkg/dev-deprecated/declarations/store/-private/utils/construct-resource.d.ts +6 -0
  287. package/dist/unpkg/dev-deprecated/declarations/store/-private/utils/is-non-empty-string.d.ts +1 -0
  288. package/dist/unpkg/dev-deprecated/declarations/store/-private/utils/normalize-model-name.d.ts +1 -0
  289. package/dist/unpkg/dev-deprecated/declarations/store/-private/utils/uuid-polyfill.d.ts +1 -0
  290. package/dist/unpkg/dev-deprecated/declarations/store/-private.d.ts +29 -0
  291. package/dist/unpkg/dev-deprecated/declarations/store/-types/q/cache-capabilities-manager.d.ts +90 -0
  292. package/dist/unpkg/dev-deprecated/declarations/store/-types/q/identifier.d.ts +23 -0
  293. package/dist/unpkg/dev-deprecated/declarations/store/-types/q/record-instance.d.ts +22 -0
  294. package/dist/unpkg/dev-deprecated/declarations/store/-types/q/store.d.ts +31 -0
  295. package/dist/unpkg/dev-deprecated/declarations/store/deprecated/-private.d.ts +223 -0
  296. package/dist/unpkg/dev-deprecated/declarations/store/deprecated/store.d.ts +784 -0
  297. package/dist/unpkg/dev-deprecated/declarations/store.d.ts +2 -0
  298. package/dist/unpkg/dev-deprecated/declarations/types/-private.d.ts +22 -0
  299. package/dist/unpkg/dev-deprecated/declarations/types/cache/aliases.d.ts +1 -0
  300. package/dist/unpkg/dev-deprecated/declarations/types/cache/change.d.ts +6 -0
  301. package/dist/unpkg/dev-deprecated/declarations/types/cache/mutations.d.ts +38 -0
  302. package/dist/unpkg/dev-deprecated/declarations/types/cache/operations.d.ts +168 -0
  303. package/dist/unpkg/dev-deprecated/declarations/types/cache/relationship.d.ts +13 -0
  304. package/dist/unpkg/dev-deprecated/declarations/types/cache.d.ts +429 -0
  305. package/dist/unpkg/dev-deprecated/declarations/types/graph.d.ts +47 -0
  306. package/dist/unpkg/dev-deprecated/declarations/types/identifier.d.ts +86 -0
  307. package/dist/unpkg/dev-deprecated/declarations/types/json/raw.d.ts +6 -0
  308. package/dist/unpkg/dev-deprecated/declarations/types/params.d.ts +8 -0
  309. package/dist/unpkg/dev-deprecated/declarations/types/record.d.ts +269 -0
  310. package/dist/unpkg/dev-deprecated/declarations/types/request.d.ts +367 -0
  311. package/dist/unpkg/dev-deprecated/declarations/types/runtime.d.ts +14 -0
  312. package/dist/unpkg/dev-deprecated/declarations/types/schema/concepts.d.ts +23 -0
  313. package/dist/unpkg/dev-deprecated/declarations/types/schema/fields.d.ts +2200 -0
  314. package/dist/unpkg/dev-deprecated/declarations/types/schema/fields.type-test.d.ts +1 -0
  315. package/dist/unpkg/dev-deprecated/declarations/types/schema/schema-service.d.ts +380 -0
  316. package/dist/unpkg/dev-deprecated/declarations/types/spec/document.d.ts +67 -0
  317. package/dist/unpkg/dev-deprecated/declarations/types/spec/error.d.ts +18 -0
  318. package/dist/unpkg/dev-deprecated/declarations/types/spec/json-api-raw.d.ts +139 -0
  319. package/dist/unpkg/dev-deprecated/declarations/types/symbols.d.ts +78 -0
  320. package/dist/unpkg/dev-deprecated/declarations/types/utils.d.ts +5 -0
  321. package/dist/unpkg/dev-deprecated/declarations/types.d.ts +11 -0
  322. package/dist/unpkg/dev-deprecated/declarations/utils/string.d.ts +47 -0
  323. package/dist/unpkg/dev-deprecated/default-cache-policy-D7_u4YRH.js +572 -0
  324. package/dist/unpkg/dev-deprecated/graph/-private.js +3374 -0
  325. package/dist/unpkg/dev-deprecated/index-D4si_DxB.js +11746 -0
  326. package/dist/unpkg/dev-deprecated/index.js +8 -0
  327. package/dist/unpkg/dev-deprecated/reactive/-private.js +1 -0
  328. package/dist/unpkg/dev-deprecated/reactive.js +129 -0
  329. package/dist/unpkg/dev-deprecated/request-oqoLC9rz.js +725 -0
  330. package/dist/unpkg/dev-deprecated/request.js +1 -0
  331. package/dist/unpkg/dev-deprecated/store/-private.js +2 -0
  332. package/dist/unpkg/dev-deprecated/store.js +1 -0
  333. package/dist/unpkg/dev-deprecated/symbols-sql1_mdx.js +39 -0
  334. package/dist/unpkg/dev-deprecated/types/-private.js +79 -0
  335. package/dist/unpkg/dev-deprecated/types/cache/aliases.js +0 -0
  336. package/dist/unpkg/dev-deprecated/types/cache/change.js +0 -0
  337. package/dist/unpkg/dev-deprecated/types/cache/mutations.js +0 -0
  338. package/dist/unpkg/dev-deprecated/types/cache/operations.js +0 -0
  339. package/dist/unpkg/dev-deprecated/types/cache/relationship.js +0 -0
  340. package/dist/unpkg/dev-deprecated/types/cache.js +0 -0
  341. package/dist/unpkg/dev-deprecated/types/graph.js +0 -0
  342. package/dist/unpkg/dev-deprecated/types/identifier.js +63 -0
  343. package/dist/unpkg/dev-deprecated/types/json/raw.js +0 -0
  344. package/dist/unpkg/dev-deprecated/types/params.js +0 -0
  345. package/dist/unpkg/dev-deprecated/types/record.js +191 -0
  346. package/dist/unpkg/dev-deprecated/types/request.js +77 -0
  347. package/dist/unpkg/dev-deprecated/types/runtime.js +34 -0
  348. package/dist/unpkg/dev-deprecated/types/schema/concepts.js +0 -0
  349. package/dist/unpkg/dev-deprecated/types/schema/fields.js +505 -0
  350. package/dist/unpkg/dev-deprecated/types/schema/fields.type-test.js +0 -0
  351. package/dist/unpkg/dev-deprecated/types/schema/schema-service.js +0 -0
  352. package/dist/unpkg/dev-deprecated/types/spec/document.js +0 -0
  353. package/dist/unpkg/dev-deprecated/types/spec/error.js +0 -0
  354. package/dist/unpkg/dev-deprecated/types/spec/json-api-raw.js +0 -0
  355. package/dist/unpkg/dev-deprecated/types/symbols.js +84 -0
  356. package/dist/unpkg/dev-deprecated/types/utils.js +0 -0
  357. package/dist/unpkg/dev-deprecated/types.js +0 -0
  358. package/dist/unpkg/dev-deprecated/utils/string.js +92 -0
  359. package/dist/unpkg/prod/build-config/babel-macros.js +1 -0
  360. package/dist/unpkg/prod/build-config/canary-features.js +1 -0
  361. package/dist/unpkg/prod/build-config/debugging.js +1 -0
  362. package/dist/unpkg/prod/build-config/deprecations.js +1 -0
  363. package/dist/unpkg/prod/build-config/env.js +1 -0
  364. package/dist/unpkg/prod/build-config/macros.js +1 -0
  365. package/dist/unpkg/prod/build-config.js +1 -0
  366. package/dist/unpkg/prod/configure-C3x8YXzL.js +181 -0
  367. package/dist/unpkg/prod/configure.js +1 -0
  368. package/dist/unpkg/prod/declarations/build-config/babel-macros.d.ts +1 -0
  369. package/dist/unpkg/prod/declarations/build-config/canary-features.d.ts +1 -0
  370. package/dist/unpkg/prod/declarations/build-config/debugging.d.ts +1 -0
  371. package/dist/unpkg/prod/declarations/build-config/deprecations.d.ts +1 -0
  372. package/dist/unpkg/prod/declarations/build-config/env.d.ts +1 -0
  373. package/dist/unpkg/prod/declarations/build-config/macros.d.ts +1 -0
  374. package/dist/unpkg/prod/declarations/build-config.d.ts +18 -0
  375. package/dist/unpkg/prod/declarations/configure.d.ts +7 -0
  376. package/dist/unpkg/prod/declarations/graph/-private/-diff.d.ts +19 -0
  377. package/dist/unpkg/prod/declarations/graph/-private/-edge-definition.d.ts +149 -0
  378. package/dist/unpkg/prod/declarations/graph/-private/-state.d.ts +9 -0
  379. package/dist/unpkg/prod/declarations/graph/-private/-utils.d.ts +25 -0
  380. package/dist/unpkg/prod/declarations/graph/-private/coerce-id.d.ts +4 -0
  381. package/dist/unpkg/prod/declarations/graph/-private/debug/assert-polymorphic-type.d.ts +6 -0
  382. package/dist/unpkg/prod/declarations/graph/-private/edges/collection.d.ts +39 -0
  383. package/dist/unpkg/prod/declarations/graph/-private/edges/implicit.d.ts +43 -0
  384. package/dist/unpkg/prod/declarations/graph/-private/edges/resource.d.ts +23 -0
  385. package/dist/unpkg/prod/declarations/graph/-private/graph.d.ts +56 -0
  386. package/dist/unpkg/prod/declarations/graph/-private/normalize-link.d.ts +2 -0
  387. package/dist/unpkg/prod/declarations/graph/-private/operations/add-to-related-records.d.ts +4 -0
  388. package/dist/unpkg/prod/declarations/graph/-private/operations/merge-identifier.d.ts +3 -0
  389. package/dist/unpkg/prod/declarations/graph/-private/operations/remove-from-related-records.d.ts +4 -0
  390. package/dist/unpkg/prod/declarations/graph/-private/operations/replace-related-record.d.ts +3 -0
  391. package/dist/unpkg/prod/declarations/graph/-private/operations/replace-related-records.d.ts +7 -0
  392. package/dist/unpkg/prod/declarations/graph/-private/operations/update-relationship.d.ts +9 -0
  393. package/dist/unpkg/prod/declarations/graph/-private.d.ts +13 -0
  394. package/dist/unpkg/prod/declarations/index.d.ts +100 -0
  395. package/dist/unpkg/prod/declarations/reactive/-private/default-mode.d.ts +73 -0
  396. package/dist/unpkg/prod/declarations/reactive/-private/document.d.ts +142 -0
  397. package/dist/unpkg/prod/declarations/reactive/-private/fields/extension.d.ts +8 -0
  398. package/dist/unpkg/prod/declarations/reactive/-private/fields/get-field-key.d.ts +8 -0
  399. package/dist/unpkg/prod/declarations/reactive/-private/fields/managed-array.d.ts +18 -0
  400. package/dist/unpkg/prod/declarations/reactive/-private/fields/managed-object.d.ts +17 -0
  401. package/dist/unpkg/prod/declarations/reactive/-private/fields/many-array-manager.d.ts +19 -0
  402. package/dist/unpkg/prod/declarations/reactive/-private/hooks.d.ts +5 -0
  403. package/dist/unpkg/prod/declarations/reactive/-private/kind/alias-field.d.ts +4 -0
  404. package/dist/unpkg/prod/declarations/reactive/-private/kind/array-field.d.ts +4 -0
  405. package/dist/unpkg/prod/declarations/reactive/-private/kind/attribute-field.d.ts +4 -0
  406. package/dist/unpkg/prod/declarations/reactive/-private/kind/belongs-to-field.d.ts +4 -0
  407. package/dist/unpkg/prod/declarations/reactive/-private/kind/collection-field.d.ts +4 -0
  408. package/dist/unpkg/prod/declarations/reactive/-private/kind/derived-field.d.ts +4 -0
  409. package/dist/unpkg/prod/declarations/reactive/-private/kind/generic-field.d.ts +4 -0
  410. package/dist/unpkg/prod/declarations/reactive/-private/kind/has-many-field.d.ts +4 -0
  411. package/dist/unpkg/prod/declarations/reactive/-private/kind/hash-field.d.ts +4 -0
  412. package/dist/unpkg/prod/declarations/reactive/-private/kind/identity-field.d.ts +4 -0
  413. package/dist/unpkg/prod/declarations/reactive/-private/kind/local-field.d.ts +4 -0
  414. package/dist/unpkg/prod/declarations/reactive/-private/kind/object-field.d.ts +4 -0
  415. package/dist/unpkg/prod/declarations/reactive/-private/kind/resource-field.d.ts +4 -0
  416. package/dist/unpkg/prod/declarations/reactive/-private/kind/schema-array-field.d.ts +4 -0
  417. package/dist/unpkg/prod/declarations/reactive/-private/kind/schema-object-field.d.ts +4 -0
  418. package/dist/unpkg/prod/declarations/reactive/-private/record.d.ts +83 -0
  419. package/dist/unpkg/prod/declarations/reactive/-private/schema.d.ts +326 -0
  420. package/dist/unpkg/prod/declarations/reactive/-private/symbols.d.ts +5 -0
  421. package/dist/unpkg/prod/declarations/reactive/-private.d.ts +2 -0
  422. package/dist/unpkg/prod/declarations/reactive.d.ts +287 -0
  423. package/dist/unpkg/prod/declarations/request/-private/context.d.ts +39 -0
  424. package/dist/unpkg/prod/declarations/request/-private/debug.d.ts +4 -0
  425. package/dist/unpkg/prod/declarations/request/-private/fetch.d.ts +33 -0
  426. package/dist/unpkg/prod/declarations/request/-private/future.d.ts +7 -0
  427. package/dist/unpkg/prod/declarations/request/-private/manager.d.ts +158 -0
  428. package/dist/unpkg/prod/declarations/request/-private/promise-cache.d.ts +28 -0
  429. package/dist/unpkg/prod/declarations/request/-private/types.d.ts +234 -0
  430. package/dist/unpkg/prod/declarations/request/-private/utils.d.ts +57 -0
  431. package/dist/unpkg/prod/declarations/request.d.ts +52 -0
  432. package/dist/unpkg/prod/declarations/store/-private/cache-handler/handler.d.ts +56 -0
  433. package/dist/unpkg/prod/declarations/store/-private/cache-handler/types.d.ts +98 -0
  434. package/dist/unpkg/prod/declarations/store/-private/cache-handler/utils.d.ts +31 -0
  435. package/dist/unpkg/prod/declarations/store/-private/caches/instance-cache.d.ts +58 -0
  436. package/dist/unpkg/prod/declarations/store/-private/caches/resource-utils.d.ts +9 -0
  437. package/dist/unpkg/prod/declarations/store/-private/debug/utils.d.ts +7 -0
  438. package/dist/unpkg/prod/declarations/store/-private/default-cache-policy.d.ts +387 -0
  439. package/dist/unpkg/prod/declarations/store/-private/managers/cache-capabilities-manager.d.ts +34 -0
  440. package/dist/unpkg/prod/declarations/store/-private/managers/cache-key-manager.d.ts +304 -0
  441. package/dist/unpkg/prod/declarations/store/-private/managers/cache-manager.d.ts +380 -0
  442. package/dist/unpkg/prod/declarations/store/-private/managers/notification-manager.d.ts +83 -0
  443. package/dist/unpkg/prod/declarations/store/-private/managers/record-array-manager.d.ts +100 -0
  444. package/dist/unpkg/prod/declarations/store/-private/network/request-cache.d.ts +103 -0
  445. package/dist/unpkg/prod/declarations/store/-private/new-core-tmp/expensive-subscription.d.ts +24 -0
  446. package/dist/unpkg/prod/declarations/store/-private/new-core-tmp/promise-state.d.ts +264 -0
  447. package/dist/unpkg/prod/declarations/store/-private/new-core-tmp/reactivity/configure.d.ts +138 -0
  448. package/dist/unpkg/prod/declarations/store/-private/new-core-tmp/reactivity/internal.d.ts +154 -0
  449. package/dist/unpkg/prod/declarations/store/-private/new-core-tmp/reactivity/signal.d.ts +56 -0
  450. package/dist/unpkg/prod/declarations/store/-private/new-core-tmp/request-state.d.ts +372 -0
  451. package/dist/unpkg/prod/declarations/store/-private/new-core-tmp/request-subscription.d.ts +177 -0
  452. package/dist/unpkg/prod/declarations/store/-private/record-arrays/-utils.d.ts +80 -0
  453. package/dist/unpkg/prod/declarations/store/-private/record-arrays/legacy-live-array.d.ts +81 -0
  454. package/dist/unpkg/prod/declarations/store/-private/record-arrays/legacy-many-array.d.ts +133 -0
  455. package/dist/unpkg/prod/declarations/store/-private/record-arrays/legacy-query.d.ts +81 -0
  456. package/dist/unpkg/prod/declarations/store/-private/record-arrays/native-proxy-type-fix.d.ts +3 -0
  457. package/dist/unpkg/prod/declarations/store/-private/record-arrays/resource-array.d.ts +67 -0
  458. package/dist/unpkg/prod/declarations/store/-private/store-service.d.ts +874 -0
  459. package/dist/unpkg/prod/declarations/store/-private/utils/coerce-id.d.ts +4 -0
  460. package/dist/unpkg/prod/declarations/store/-private/utils/construct-resource.d.ts +6 -0
  461. package/dist/unpkg/prod/declarations/store/-private/utils/is-non-empty-string.d.ts +1 -0
  462. package/dist/unpkg/prod/declarations/store/-private/utils/normalize-model-name.d.ts +1 -0
  463. package/dist/unpkg/prod/declarations/store/-private/utils/uuid-polyfill.d.ts +1 -0
  464. package/dist/unpkg/prod/declarations/store/-private.d.ts +29 -0
  465. package/dist/unpkg/prod/declarations/store/-types/q/cache-capabilities-manager.d.ts +90 -0
  466. package/dist/unpkg/prod/declarations/store/-types/q/identifier.d.ts +23 -0
  467. package/dist/unpkg/prod/declarations/store/-types/q/record-instance.d.ts +22 -0
  468. package/dist/unpkg/prod/declarations/store/-types/q/store.d.ts +31 -0
  469. package/dist/unpkg/prod/declarations/store/deprecated/-private.d.ts +223 -0
  470. package/dist/unpkg/prod/declarations/store/deprecated/store.d.ts +784 -0
  471. package/dist/unpkg/prod/declarations/store.d.ts +2 -0
  472. package/dist/unpkg/prod/declarations/types/-private.d.ts +22 -0
  473. package/dist/unpkg/prod/declarations/types/cache/aliases.d.ts +1 -0
  474. package/dist/unpkg/prod/declarations/types/cache/change.d.ts +6 -0
  475. package/dist/unpkg/prod/declarations/types/cache/mutations.d.ts +38 -0
  476. package/dist/unpkg/prod/declarations/types/cache/operations.d.ts +168 -0
  477. package/dist/unpkg/prod/declarations/types/cache/relationship.d.ts +13 -0
  478. package/dist/unpkg/prod/declarations/types/cache.d.ts +429 -0
  479. package/dist/unpkg/prod/declarations/types/graph.d.ts +47 -0
  480. package/dist/unpkg/prod/declarations/types/identifier.d.ts +86 -0
  481. package/dist/unpkg/prod/declarations/types/json/raw.d.ts +6 -0
  482. package/dist/unpkg/prod/declarations/types/params.d.ts +8 -0
  483. package/dist/unpkg/prod/declarations/types/record.d.ts +269 -0
  484. package/dist/unpkg/prod/declarations/types/request.d.ts +367 -0
  485. package/dist/unpkg/prod/declarations/types/runtime.d.ts +14 -0
  486. package/dist/unpkg/prod/declarations/types/schema/concepts.d.ts +23 -0
  487. package/dist/unpkg/prod/declarations/types/schema/fields.d.ts +2200 -0
  488. package/dist/unpkg/prod/declarations/types/schema/fields.type-test.d.ts +1 -0
  489. package/dist/unpkg/prod/declarations/types/schema/schema-service.d.ts +380 -0
  490. package/dist/unpkg/prod/declarations/types/spec/document.d.ts +67 -0
  491. package/dist/unpkg/prod/declarations/types/spec/error.d.ts +18 -0
  492. package/dist/unpkg/prod/declarations/types/spec/json-api-raw.d.ts +139 -0
  493. package/dist/unpkg/prod/declarations/types/symbols.d.ts +78 -0
  494. package/dist/unpkg/prod/declarations/types/utils.d.ts +5 -0
  495. package/dist/unpkg/prod/declarations/types.d.ts +11 -0
  496. package/dist/unpkg/prod/declarations/utils/string.d.ts +47 -0
  497. package/dist/unpkg/prod/default-cache-policy-D7_u4YRH.js +572 -0
  498. package/dist/unpkg/prod/graph/-private.js +3374 -0
  499. package/dist/unpkg/prod/index-D4si_DxB.js +11746 -0
  500. package/dist/unpkg/prod/index.js +8 -0
  501. package/dist/unpkg/prod/reactive/-private.js +1 -0
  502. package/dist/unpkg/prod/reactive.js +129 -0
  503. package/dist/unpkg/prod/request-oqoLC9rz.js +725 -0
  504. package/dist/unpkg/prod/request.js +1 -0
  505. package/dist/unpkg/prod/store/-private.js +2 -0
  506. package/dist/unpkg/prod/store.js +1 -0
  507. package/dist/unpkg/prod/symbols-sql1_mdx.js +39 -0
  508. package/dist/unpkg/prod/types/-private.js +79 -0
  509. package/dist/unpkg/prod/types/cache/aliases.js +0 -0
  510. package/dist/unpkg/prod/types/cache/change.js +0 -0
  511. package/dist/unpkg/prod/types/cache/mutations.js +0 -0
  512. package/dist/unpkg/prod/types/cache/operations.js +0 -0
  513. package/dist/unpkg/prod/types/cache/relationship.js +0 -0
  514. package/dist/unpkg/prod/types/cache.js +0 -0
  515. package/dist/unpkg/prod/types/graph.js +0 -0
  516. package/dist/unpkg/prod/types/identifier.js +63 -0
  517. package/dist/unpkg/prod/types/json/raw.js +0 -0
  518. package/dist/unpkg/prod/types/params.js +0 -0
  519. package/dist/unpkg/prod/types/record.js +191 -0
  520. package/dist/unpkg/prod/types/request.js +77 -0
  521. package/dist/unpkg/prod/types/runtime.js +34 -0
  522. package/dist/unpkg/prod/types/schema/concepts.js +0 -0
  523. package/dist/unpkg/prod/types/schema/fields.js +505 -0
  524. package/dist/unpkg/prod/types/schema/fields.type-test.js +0 -0
  525. package/dist/unpkg/prod/types/schema/schema-service.js +0 -0
  526. package/dist/unpkg/prod/types/spec/document.js +0 -0
  527. package/dist/unpkg/prod/types/spec/error.js +0 -0
  528. package/dist/unpkg/prod/types/spec/json-api-raw.js +0 -0
  529. package/dist/unpkg/prod/types/symbols.js +84 -0
  530. package/dist/unpkg/prod/types/utils.js +0 -0
  531. package/dist/unpkg/prod/types.js +0 -0
  532. package/dist/unpkg/prod/utils/string.js +92 -0
  533. package/dist/unpkg/prod-deprecated/build-config/babel-macros.js +1 -0
  534. package/dist/unpkg/prod-deprecated/build-config/canary-features.js +1 -0
  535. package/dist/unpkg/prod-deprecated/build-config/debugging.js +1 -0
  536. package/dist/unpkg/prod-deprecated/build-config/deprecations.js +1 -0
  537. package/dist/unpkg/prod-deprecated/build-config/env.js +1 -0
  538. package/dist/unpkg/prod-deprecated/build-config/macros.js +1 -0
  539. package/dist/unpkg/prod-deprecated/build-config.js +1 -0
  540. package/dist/unpkg/prod-deprecated/configure-C3x8YXzL.js +181 -0
  541. package/dist/unpkg/prod-deprecated/configure.js +1 -0
  542. package/dist/unpkg/prod-deprecated/declarations/build-config/babel-macros.d.ts +1 -0
  543. package/dist/unpkg/prod-deprecated/declarations/build-config/canary-features.d.ts +1 -0
  544. package/dist/unpkg/prod-deprecated/declarations/build-config/debugging.d.ts +1 -0
  545. package/dist/unpkg/prod-deprecated/declarations/build-config/deprecations.d.ts +1 -0
  546. package/dist/unpkg/prod-deprecated/declarations/build-config/env.d.ts +1 -0
  547. package/dist/unpkg/prod-deprecated/declarations/build-config/macros.d.ts +1 -0
  548. package/dist/unpkg/prod-deprecated/declarations/build-config.d.ts +18 -0
  549. package/dist/unpkg/prod-deprecated/declarations/configure.d.ts +7 -0
  550. package/dist/unpkg/prod-deprecated/declarations/graph/-private/-diff.d.ts +19 -0
  551. package/dist/unpkg/prod-deprecated/declarations/graph/-private/-edge-definition.d.ts +149 -0
  552. package/dist/unpkg/prod-deprecated/declarations/graph/-private/-state.d.ts +9 -0
  553. package/dist/unpkg/prod-deprecated/declarations/graph/-private/-utils.d.ts +25 -0
  554. package/dist/unpkg/prod-deprecated/declarations/graph/-private/coerce-id.d.ts +4 -0
  555. package/dist/unpkg/prod-deprecated/declarations/graph/-private/debug/assert-polymorphic-type.d.ts +6 -0
  556. package/dist/unpkg/prod-deprecated/declarations/graph/-private/edges/collection.d.ts +39 -0
  557. package/dist/unpkg/prod-deprecated/declarations/graph/-private/edges/implicit.d.ts +43 -0
  558. package/dist/unpkg/prod-deprecated/declarations/graph/-private/edges/resource.d.ts +23 -0
  559. package/dist/unpkg/prod-deprecated/declarations/graph/-private/graph.d.ts +56 -0
  560. package/dist/unpkg/prod-deprecated/declarations/graph/-private/normalize-link.d.ts +2 -0
  561. package/dist/unpkg/prod-deprecated/declarations/graph/-private/operations/add-to-related-records.d.ts +4 -0
  562. package/dist/unpkg/prod-deprecated/declarations/graph/-private/operations/merge-identifier.d.ts +3 -0
  563. package/dist/unpkg/prod-deprecated/declarations/graph/-private/operations/remove-from-related-records.d.ts +4 -0
  564. package/dist/unpkg/prod-deprecated/declarations/graph/-private/operations/replace-related-record.d.ts +3 -0
  565. package/dist/unpkg/prod-deprecated/declarations/graph/-private/operations/replace-related-records.d.ts +7 -0
  566. package/dist/unpkg/prod-deprecated/declarations/graph/-private/operations/update-relationship.d.ts +9 -0
  567. package/dist/unpkg/prod-deprecated/declarations/graph/-private.d.ts +13 -0
  568. package/dist/unpkg/prod-deprecated/declarations/index.d.ts +100 -0
  569. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/default-mode.d.ts +73 -0
  570. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/document.d.ts +142 -0
  571. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/fields/extension.d.ts +8 -0
  572. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/fields/get-field-key.d.ts +8 -0
  573. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/fields/managed-array.d.ts +18 -0
  574. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/fields/managed-object.d.ts +17 -0
  575. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/fields/many-array-manager.d.ts +19 -0
  576. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/hooks.d.ts +5 -0
  577. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/kind/alias-field.d.ts +4 -0
  578. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/kind/array-field.d.ts +4 -0
  579. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/kind/attribute-field.d.ts +4 -0
  580. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/kind/belongs-to-field.d.ts +4 -0
  581. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/kind/collection-field.d.ts +4 -0
  582. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/kind/derived-field.d.ts +4 -0
  583. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/kind/generic-field.d.ts +4 -0
  584. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/kind/has-many-field.d.ts +4 -0
  585. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/kind/hash-field.d.ts +4 -0
  586. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/kind/identity-field.d.ts +4 -0
  587. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/kind/local-field.d.ts +4 -0
  588. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/kind/object-field.d.ts +4 -0
  589. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/kind/resource-field.d.ts +4 -0
  590. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/kind/schema-array-field.d.ts +4 -0
  591. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/kind/schema-object-field.d.ts +4 -0
  592. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/record.d.ts +83 -0
  593. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/schema.d.ts +326 -0
  594. package/dist/unpkg/prod-deprecated/declarations/reactive/-private/symbols.d.ts +5 -0
  595. package/dist/unpkg/prod-deprecated/declarations/reactive/-private.d.ts +2 -0
  596. package/dist/unpkg/prod-deprecated/declarations/reactive.d.ts +287 -0
  597. package/dist/unpkg/prod-deprecated/declarations/request/-private/context.d.ts +39 -0
  598. package/dist/unpkg/prod-deprecated/declarations/request/-private/debug.d.ts +4 -0
  599. package/dist/unpkg/prod-deprecated/declarations/request/-private/fetch.d.ts +33 -0
  600. package/dist/unpkg/prod-deprecated/declarations/request/-private/future.d.ts +7 -0
  601. package/dist/unpkg/prod-deprecated/declarations/request/-private/manager.d.ts +158 -0
  602. package/dist/unpkg/prod-deprecated/declarations/request/-private/promise-cache.d.ts +28 -0
  603. package/dist/unpkg/prod-deprecated/declarations/request/-private/types.d.ts +234 -0
  604. package/dist/unpkg/prod-deprecated/declarations/request/-private/utils.d.ts +57 -0
  605. package/dist/unpkg/prod-deprecated/declarations/request.d.ts +52 -0
  606. package/dist/unpkg/prod-deprecated/declarations/store/-private/cache-handler/handler.d.ts +56 -0
  607. package/dist/unpkg/prod-deprecated/declarations/store/-private/cache-handler/types.d.ts +98 -0
  608. package/dist/unpkg/prod-deprecated/declarations/store/-private/cache-handler/utils.d.ts +31 -0
  609. package/dist/unpkg/prod-deprecated/declarations/store/-private/caches/instance-cache.d.ts +58 -0
  610. package/dist/unpkg/prod-deprecated/declarations/store/-private/caches/resource-utils.d.ts +9 -0
  611. package/dist/unpkg/prod-deprecated/declarations/store/-private/debug/utils.d.ts +7 -0
  612. package/dist/unpkg/prod-deprecated/declarations/store/-private/default-cache-policy.d.ts +387 -0
  613. package/dist/unpkg/prod-deprecated/declarations/store/-private/managers/cache-capabilities-manager.d.ts +34 -0
  614. package/dist/unpkg/prod-deprecated/declarations/store/-private/managers/cache-key-manager.d.ts +304 -0
  615. package/dist/unpkg/prod-deprecated/declarations/store/-private/managers/cache-manager.d.ts +380 -0
  616. package/dist/unpkg/prod-deprecated/declarations/store/-private/managers/notification-manager.d.ts +83 -0
  617. package/dist/unpkg/prod-deprecated/declarations/store/-private/managers/record-array-manager.d.ts +100 -0
  618. package/dist/unpkg/prod-deprecated/declarations/store/-private/network/request-cache.d.ts +103 -0
  619. package/dist/unpkg/prod-deprecated/declarations/store/-private/new-core-tmp/expensive-subscription.d.ts +24 -0
  620. package/dist/unpkg/prod-deprecated/declarations/store/-private/new-core-tmp/promise-state.d.ts +264 -0
  621. package/dist/unpkg/prod-deprecated/declarations/store/-private/new-core-tmp/reactivity/configure.d.ts +138 -0
  622. package/dist/unpkg/prod-deprecated/declarations/store/-private/new-core-tmp/reactivity/internal.d.ts +154 -0
  623. package/dist/unpkg/prod-deprecated/declarations/store/-private/new-core-tmp/reactivity/signal.d.ts +56 -0
  624. package/dist/unpkg/prod-deprecated/declarations/store/-private/new-core-tmp/request-state.d.ts +372 -0
  625. package/dist/unpkg/prod-deprecated/declarations/store/-private/new-core-tmp/request-subscription.d.ts +177 -0
  626. package/dist/unpkg/prod-deprecated/declarations/store/-private/record-arrays/-utils.d.ts +80 -0
  627. package/dist/unpkg/prod-deprecated/declarations/store/-private/record-arrays/legacy-live-array.d.ts +81 -0
  628. package/dist/unpkg/prod-deprecated/declarations/store/-private/record-arrays/legacy-many-array.d.ts +133 -0
  629. package/dist/unpkg/prod-deprecated/declarations/store/-private/record-arrays/legacy-query.d.ts +81 -0
  630. package/dist/unpkg/prod-deprecated/declarations/store/-private/record-arrays/native-proxy-type-fix.d.ts +3 -0
  631. package/dist/unpkg/prod-deprecated/declarations/store/-private/record-arrays/resource-array.d.ts +67 -0
  632. package/dist/unpkg/prod-deprecated/declarations/store/-private/store-service.d.ts +874 -0
  633. package/dist/unpkg/prod-deprecated/declarations/store/-private/utils/coerce-id.d.ts +4 -0
  634. package/dist/unpkg/prod-deprecated/declarations/store/-private/utils/construct-resource.d.ts +6 -0
  635. package/dist/unpkg/prod-deprecated/declarations/store/-private/utils/is-non-empty-string.d.ts +1 -0
  636. package/dist/unpkg/prod-deprecated/declarations/store/-private/utils/normalize-model-name.d.ts +1 -0
  637. package/dist/unpkg/prod-deprecated/declarations/store/-private/utils/uuid-polyfill.d.ts +1 -0
  638. package/dist/unpkg/prod-deprecated/declarations/store/-private.d.ts +29 -0
  639. package/dist/unpkg/prod-deprecated/declarations/store/-types/q/cache-capabilities-manager.d.ts +90 -0
  640. package/dist/unpkg/prod-deprecated/declarations/store/-types/q/identifier.d.ts +23 -0
  641. package/dist/unpkg/prod-deprecated/declarations/store/-types/q/record-instance.d.ts +22 -0
  642. package/dist/unpkg/prod-deprecated/declarations/store/-types/q/store.d.ts +31 -0
  643. package/dist/unpkg/prod-deprecated/declarations/store/deprecated/-private.d.ts +223 -0
  644. package/dist/unpkg/prod-deprecated/declarations/store/deprecated/store.d.ts +784 -0
  645. package/dist/unpkg/prod-deprecated/declarations/store.d.ts +2 -0
  646. package/dist/unpkg/prod-deprecated/declarations/types/-private.d.ts +22 -0
  647. package/dist/unpkg/prod-deprecated/declarations/types/cache/aliases.d.ts +1 -0
  648. package/dist/unpkg/prod-deprecated/declarations/types/cache/change.d.ts +6 -0
  649. package/dist/unpkg/prod-deprecated/declarations/types/cache/mutations.d.ts +38 -0
  650. package/dist/unpkg/prod-deprecated/declarations/types/cache/operations.d.ts +168 -0
  651. package/dist/unpkg/prod-deprecated/declarations/types/cache/relationship.d.ts +13 -0
  652. package/dist/unpkg/prod-deprecated/declarations/types/cache.d.ts +429 -0
  653. package/dist/unpkg/prod-deprecated/declarations/types/graph.d.ts +47 -0
  654. package/dist/unpkg/prod-deprecated/declarations/types/identifier.d.ts +86 -0
  655. package/dist/unpkg/prod-deprecated/declarations/types/json/raw.d.ts +6 -0
  656. package/dist/unpkg/prod-deprecated/declarations/types/params.d.ts +8 -0
  657. package/dist/unpkg/prod-deprecated/declarations/types/record.d.ts +269 -0
  658. package/dist/unpkg/prod-deprecated/declarations/types/request.d.ts +367 -0
  659. package/dist/unpkg/prod-deprecated/declarations/types/runtime.d.ts +14 -0
  660. package/dist/unpkg/prod-deprecated/declarations/types/schema/concepts.d.ts +23 -0
  661. package/dist/unpkg/prod-deprecated/declarations/types/schema/fields.d.ts +2200 -0
  662. package/dist/unpkg/prod-deprecated/declarations/types/schema/fields.type-test.d.ts +1 -0
  663. package/dist/unpkg/prod-deprecated/declarations/types/schema/schema-service.d.ts +380 -0
  664. package/dist/unpkg/prod-deprecated/declarations/types/spec/document.d.ts +67 -0
  665. package/dist/unpkg/prod-deprecated/declarations/types/spec/error.d.ts +18 -0
  666. package/dist/unpkg/prod-deprecated/declarations/types/spec/json-api-raw.d.ts +139 -0
  667. package/dist/unpkg/prod-deprecated/declarations/types/symbols.d.ts +78 -0
  668. package/dist/unpkg/prod-deprecated/declarations/types/utils.d.ts +5 -0
  669. package/dist/unpkg/prod-deprecated/declarations/types.d.ts +11 -0
  670. package/dist/unpkg/prod-deprecated/declarations/utils/string.d.ts +47 -0
  671. package/dist/unpkg/prod-deprecated/default-cache-policy-D7_u4YRH.js +572 -0
  672. package/dist/unpkg/prod-deprecated/graph/-private.js +3374 -0
  673. package/dist/unpkg/prod-deprecated/index-D4si_DxB.js +11746 -0
  674. package/dist/unpkg/prod-deprecated/index.js +8 -0
  675. package/dist/unpkg/prod-deprecated/reactive/-private.js +1 -0
  676. package/dist/unpkg/prod-deprecated/reactive.js +129 -0
  677. package/dist/unpkg/prod-deprecated/request-oqoLC9rz.js +725 -0
  678. package/dist/unpkg/prod-deprecated/request.js +1 -0
  679. package/dist/unpkg/prod-deprecated/store/-private.js +2 -0
  680. package/dist/unpkg/prod-deprecated/store.js +1 -0
  681. package/dist/unpkg/prod-deprecated/symbols-sql1_mdx.js +39 -0
  682. package/dist/unpkg/prod-deprecated/types/-private.js +79 -0
  683. package/dist/unpkg/prod-deprecated/types/cache/aliases.js +0 -0
  684. package/dist/unpkg/prod-deprecated/types/cache/change.js +0 -0
  685. package/dist/unpkg/prod-deprecated/types/cache/mutations.js +0 -0
  686. package/dist/unpkg/prod-deprecated/types/cache/operations.js +0 -0
  687. package/dist/unpkg/prod-deprecated/types/cache/relationship.js +0 -0
  688. package/dist/unpkg/prod-deprecated/types/cache.js +0 -0
  689. package/dist/unpkg/prod-deprecated/types/graph.js +0 -0
  690. package/dist/unpkg/prod-deprecated/types/identifier.js +63 -0
  691. package/dist/unpkg/prod-deprecated/types/json/raw.js +0 -0
  692. package/dist/unpkg/prod-deprecated/types/params.js +0 -0
  693. package/dist/unpkg/prod-deprecated/types/record.js +191 -0
  694. package/dist/unpkg/prod-deprecated/types/request.js +77 -0
  695. package/dist/unpkg/prod-deprecated/types/runtime.js +34 -0
  696. package/dist/unpkg/prod-deprecated/types/schema/concepts.js +0 -0
  697. package/dist/unpkg/prod-deprecated/types/schema/fields.js +505 -0
  698. package/dist/unpkg/prod-deprecated/types/schema/fields.type-test.js +0 -0
  699. package/dist/unpkg/prod-deprecated/types/schema/schema-service.js +0 -0
  700. package/dist/unpkg/prod-deprecated/types/spec/document.js +0 -0
  701. package/dist/unpkg/prod-deprecated/types/spec/error.js +0 -0
  702. package/dist/unpkg/prod-deprecated/types/spec/json-api-raw.js +0 -0
  703. package/dist/unpkg/prod-deprecated/types/symbols.js +84 -0
  704. package/dist/unpkg/prod-deprecated/types/utils.js +0 -0
  705. package/dist/unpkg/prod-deprecated/types.js +0 -0
  706. package/dist/unpkg/prod-deprecated/utils/string.js +92 -0
  707. package/package.json +27 -3
@@ -0,0 +1,3374 @@
1
+ import { deprecate, warn } from '@ember/debug';
2
+ import { macroCondition, getGlobalConfig } from '@embroider/macros';
3
+ import { getOrSetGlobal, peekTransient, setTransient } from '../types/-private.js';
4
+ function coerceId(id) {
5
+ if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_NON_STRICT_ID)) {
6
+ let normalized;
7
+ if (id === null || id === undefined || id === '') {
8
+ normalized = null;
9
+ } else {
10
+ normalized = String(id);
11
+ }
12
+ deprecate(`The resource id '<${typeof id}> ${String(id)} ' is not normalized. Update your application code to use '${JSON.stringify(normalized)}' instead.`, normalized === id, {
13
+ id: 'ember-data:deprecate-non-strict-id',
14
+ until: '6.0',
15
+ for: 'ember-data',
16
+ since: {
17
+ available: '4.13',
18
+ enabled: '5.3'
19
+ }
20
+ });
21
+ return normalized;
22
+ }
23
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
24
+ if (!test) {
25
+ throw new Error(`Resource IDs must be a non-empty string or null. Received '${String(id)}'.`);
26
+ }
27
+ })(id === null || typeof id === 'string' && id.length > 0) : {};
28
+ return id;
29
+ }
30
+ function getStore(wrapper) {
31
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
32
+ if (!test) {
33
+ throw new Error(`expected a private _store property`);
34
+ }
35
+ })('_store' in wrapper) : {};
36
+ return wrapper._store;
37
+ }
38
+ function expandingGet(cache, key1, key2) {
39
+ const mainCache = cache[key1] = cache[key1] || Object.create(null);
40
+ return mainCache[key2];
41
+ }
42
+ function expandingSet(cache, key1, key2, value) {
43
+ const mainCache = cache[key1] = cache[key1] || Object.create(null);
44
+ mainCache[key2] = value;
45
+ }
46
+ function assertValidRelationshipPayload(graph, op) {
47
+ const relationship = graph.get(op.record, op.field);
48
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
49
+ if (!test) {
50
+ throw new Error(`Cannot update an implicit relationship`);
51
+ }
52
+ })(isHasMany(relationship) || isBelongsTo(relationship)) : {};
53
+ const payload = op.value;
54
+ const {
55
+ definition,
56
+ identifier,
57
+ state
58
+ } = relationship;
59
+ const {
60
+ type
61
+ } = identifier;
62
+ const {
63
+ field
64
+ } = op;
65
+ const {
66
+ isAsync,
67
+ kind
68
+ } = definition;
69
+ if (payload.links) {
70
+ warn(`You pushed a record of type '${type}' with a relationship '${field}' configured as 'async: false'. You've included a link but no primary data, this may be an error in your payload. WarpDrive will treat this relationship as known-to-be-empty.`, isAsync || !!payload.data || state.hasReceivedData, {
71
+ id: 'ds.store.push-link-for-sync-relationship'
72
+ });
73
+ } else if (payload.data) {
74
+ if (kind === 'belongsTo') {
75
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
76
+ if (!test) {
77
+ throw new Error(`A ${type} record was pushed into the store with the value of ${field} being ${inspect(payload.data)}, but ${field} is a belongsTo relationship so the value must not be an array. You should probably check your data payload or serializer.`);
78
+ }
79
+ })(!Array.isArray(payload.data)) : {};
80
+ assertRelationshipData(getStore(graph.store), identifier, payload.data, definition);
81
+ } else if (kind === 'hasMany') {
82
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
83
+ if (!test) {
84
+ throw new Error(`A ${type} record was pushed into the store with the value of ${field} being '${inspect(payload.data)}', but ${field} is a hasMany relationship so the value must be an array. You should probably check your data payload or serializer.`);
85
+ }
86
+ })(Array.isArray(payload.data)) : {};
87
+ if (Array.isArray(payload.data)) {
88
+ for (let i = 0; i < payload.data.length; i++) {
89
+ assertRelationshipData(getStore(graph.store), identifier, payload.data[i], definition);
90
+ }
91
+ }
92
+ }
93
+ }
94
+ }
95
+ function inspect(value) {
96
+ const type = typeof value;
97
+ if (value === null) {
98
+ return 'null';
99
+ }
100
+ if (type !== 'object') {
101
+ return type;
102
+ }
103
+ if (Array.isArray(value)) {
104
+ return 'Array';
105
+ }
106
+ if (value instanceof Date) {
107
+ return 'Date';
108
+ }
109
+ if (value instanceof RegExp) {
110
+ return 'RegExp';
111
+ }
112
+ if (value instanceof Map) {
113
+ return 'Map';
114
+ }
115
+ if (value instanceof Set) {
116
+ return 'Set';
117
+ }
118
+ return 'object';
119
+ }
120
+ function checkIfNew(store, resourceKey) {
121
+ if (!resourceKey.id) {
122
+ return true;
123
+ }
124
+ return store.cache.isNew(resourceKey);
125
+ }
126
+ function isBelongsTo(relationship) {
127
+ return relationship.definition.kind === 'belongsTo';
128
+ }
129
+ function isImplicit(relationship) {
130
+ return relationship.definition.isImplicit;
131
+ }
132
+ function isHasMany(relationship) {
133
+ return relationship.definition.kind === 'hasMany';
134
+ }
135
+ function forAllRelatedIdentifiers(rel, cb) {
136
+ if (isBelongsTo(rel)) {
137
+ if (rel.remoteState) {
138
+ cb(rel.remoteState);
139
+ }
140
+ if (rel.localState && rel.localState !== rel.remoteState) {
141
+ cb(rel.localState);
142
+ }
143
+ } else if (isHasMany(rel)) {
144
+ // TODO
145
+ // rel.remoteMembers.forEach(cb);
146
+ // might be simpler if performance is not a concern
147
+ for (let i = 0; i < rel.remoteState.length; i++) {
148
+ const inverseIdentifier = rel.remoteState[i];
149
+ cb(inverseIdentifier);
150
+ }
151
+ rel.additions?.forEach(cb);
152
+ } else {
153
+ rel.localMembers.forEach(cb);
154
+ rel.remoteMembers.forEach(inverseIdentifier => {
155
+ if (!rel.localMembers.has(inverseIdentifier)) {
156
+ cb(inverseIdentifier);
157
+ }
158
+ });
159
+ }
160
+ }
161
+
162
+ /*
163
+ Removes the given identifier from BOTH remote AND local state.
164
+
165
+ This method is useful when either a deletion or a rollback on a new record
166
+ needs to entirely purge itself from an inverse relationship.
167
+ */
168
+ function removeIdentifierCompletelyFromRelationship(graph, relationship, value, silenceNotifications) {
169
+ if (isBelongsTo(relationship)) {
170
+ if (relationship.remoteState === value) {
171
+ relationship.remoteState = null;
172
+ }
173
+ if (relationship.localState === value) {
174
+ relationship.localState = null;
175
+ // This allows dematerialized inverses to be rematerialized
176
+ // we shouldn't be notifying here though, figure out where
177
+ // a notification was missed elsewhere.
178
+ {
179
+ notifyChange(graph, relationship);
180
+ }
181
+ }
182
+ } else if (isHasMany(relationship)) {
183
+ relationship.remoteMembers.delete(value);
184
+ relationship.additions?.delete(value);
185
+ const wasInRemovals = relationship.removals?.delete(value);
186
+ const canonicalIndex = relationship.remoteState.indexOf(value);
187
+ if (canonicalIndex !== -1) {
188
+ relationship.remoteState.splice(canonicalIndex, 1);
189
+ }
190
+ if (!wasInRemovals) {
191
+ const currentIndex = relationship.localState?.indexOf(value);
192
+ if (currentIndex !== -1 && currentIndex !== undefined) {
193
+ relationship.localState.splice(currentIndex, 1);
194
+ // This allows dematerialized inverses to be rematerialized
195
+ // we shouldn't be notifying here though, figure out where
196
+ // a notification was missed elsewhere.
197
+ {
198
+ notifyChange(graph, relationship);
199
+ }
200
+ }
201
+ }
202
+ } else {
203
+ relationship.remoteMembers.delete(value);
204
+ relationship.localMembers.delete(value);
205
+ }
206
+ }
207
+ function notifyChange(graph, relationship) {
208
+ if (!relationship.accessed) {
209
+ return;
210
+ }
211
+ const resourceKey = relationship.identifier;
212
+ const key = relationship.definition.key;
213
+ if (resourceKey === graph._removing) {
214
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_GRAPH)) {
215
+ if (getGlobalConfig().WarpDrive.debug.LOG_GRAPH || globalThis.getWarpDriveRuntimeConfig().debug.LOG_GRAPH) {
216
+ // eslint-disable-next-line no-console
217
+ console.log(`Graph: ignoring relationship change for removed identifier ${String(resourceKey)} ${key}`);
218
+ }
219
+ }
220
+ return;
221
+ }
222
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_GRAPH)) {
223
+ if (getGlobalConfig().WarpDrive.debug.LOG_GRAPH || globalThis.getWarpDriveRuntimeConfig().debug.LOG_GRAPH) {
224
+ // eslint-disable-next-line no-console
225
+ console.log(`Graph: notifying relationship change for ${String(resourceKey)} ${key}`);
226
+ }
227
+ }
228
+ graph.store.notifyChange(resourceKey, 'relationships', key);
229
+ }
230
+ function assertRelationshipData(store, resourceKey, data, meta) {
231
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
232
+ if (!test) {
233
+ throw new Error(`A ${resourceKey.type} record was pushed into the store with the value of ${meta.key} being '${JSON.stringify(data)}', but ${meta.key} is a belongsTo relationship so the value must not be an array. You should probably check your data payload or serializer.`);
234
+ }
235
+ })(!Array.isArray(data)) : {};
236
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
237
+ if (!test) {
238
+ throw new Error(`Encountered a relationship identifier without a type for the ${meta.kind} relationship '${meta.key}' on <${resourceKey.type}:${String(resourceKey.id)}>, expected an identifier with type '${meta.type}' but found\n\n'${JSON.stringify(data, null, 2)}'\n\nPlease check your serializer and make sure it is serializing the relationship payload into a JSON API format.`);
239
+ }
240
+ })(data === null || 'type' in data && typeof data.type === 'string' && data.type.length) : {};
241
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
242
+ if (!test) {
243
+ throw new Error(`Encountered a relationship identifier without an id for the ${meta.kind} relationship '${meta.key}' on <${resourceKey.type}:${String(resourceKey.id)}>, expected an identifier but found\n\n'${JSON.stringify(data, null, 2)}'\n\nPlease check your serializer and make sure it is serializing the relationship payload into a JSON API format.`);
244
+ }
245
+ })(data === null || !!coerceId(data.id)) : {};
246
+ if (data?.type === meta.type) {
247
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
248
+ if (!test) {
249
+ throw new Error(`Missing Schema: Encountered a relationship identifier { type: '${data.type}', id: '${String(data.id)}' } for the '${resourceKey.type}.${meta.key}' ${meta.kind} relationship on <${resourceKey.type}:${String(resourceKey.id)}>, but no schema exists for that type.`);
250
+ }
251
+ })(store.schema.hasResource(data)) : {};
252
+ } else {
253
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
254
+ if (!test) {
255
+ throw new Error(`Missing Schema: Encountered a relationship identifier with type '${data.type}' for the ${meta.kind} relationship '${meta.key}' on <${resourceKey.type}:${String(resourceKey.id)}>, Expected an identifier with type '${meta.type}'. No schema was found for '${data.type}'.`);
256
+ }
257
+ })(data === null || !data.type || store.schema.hasResource(data)) : {};
258
+ }
259
+ }
260
+ const RELATIONSHIP_KINDS = ['belongsTo', 'hasMany', 'resource', 'collection'];
261
+ function isLegacyField(field) {
262
+ return field.kind === 'belongsTo' || field.kind === 'hasMany';
263
+ }
264
+ function isRelationshipField(field) {
265
+ return RELATIONSHIP_KINDS.includes(field.kind);
266
+ }
267
+ function temporaryConvertToLegacy(field) {
268
+ return {
269
+ kind: field.kind === 'resource' ? 'belongsTo' : 'hasMany',
270
+ name: field.name,
271
+ type: field.type,
272
+ options: Object.assign({}, {
273
+ async: false,
274
+ inverse: null,
275
+ resetOnRemoteUpdate: false
276
+ }, field.options)
277
+ };
278
+ }
279
+
280
+ /**
281
+ *
282
+ * Given RHS (Right Hand Side)
283
+ *
284
+ * ```ts
285
+ * class User extends Model {
286
+ * @hasMany('animal', { async: false, inverse: 'owner' }) pets;
287
+ * }
288
+ * ```
289
+ *
290
+ * Given LHS (Left Hand Side)
291
+ *
292
+ * ```ts
293
+ * class Animal extends Model {
294
+ * @belongsTo('user', { async: false, inverse: 'pets' }) owner;
295
+ * }
296
+ * ```
297
+ *
298
+ * The UpgradedMeta for the RHS would be:
299
+ *
300
+ * ```ts
301
+ * {
302
+ * kind: 'hasMany',
303
+ * key: 'pets',
304
+ * type: 'animal',
305
+ * isAsync: false,
306
+ * isImplicit: false,
307
+ * isCollection: true,
308
+ * isPolymorphic: false,
309
+ * inverseKind: 'belongsTo',
310
+ * inverseKey: 'owner',
311
+ * inverseType: 'user',
312
+ * inverseIsAsync: false,
313
+ * inverseIsImplicit: false,
314
+ * inverseIsCollection: false,
315
+ * inverseIsPolymorphic: false,
316
+ * }
317
+ * ```
318
+ *
319
+ * The UpgradeMeta for the LHS would be:
320
+ *
321
+ * ```ts
322
+ * {
323
+ * kind: 'belongsTo',
324
+ * key: 'owner',
325
+ * type: 'user',
326
+ * isAsync: false,
327
+ * isImplicit: false,
328
+ * isCollection: false,
329
+ * isPolymorphic: false,
330
+ * inverseKind: 'hasMany',
331
+ * inverseKey: 'pets',
332
+ * inverseType: 'animal',
333
+ * inverseIsAsync: false,
334
+ * inverseIsImplicit: false,
335
+ * inverseIsCollection: true,
336
+ * inverseIsPolymorphic: false,
337
+ * }
338
+ * ```
339
+ *
340
+ * @private
341
+ */
342
+
343
+ const BOOL_LATER = null;
344
+ const STR_LATER = '';
345
+ const IMPLICIT_KEY_RAND = Date.now();
346
+ function implicitKeyFor(type, key) {
347
+ return `implicit-${type}:${key}${IMPLICIT_KEY_RAND}`;
348
+ }
349
+ function syncMeta(definition, inverseDefinition) {
350
+ definition.inverseKind = inverseDefinition.kind;
351
+ definition.inverseKey = inverseDefinition.key;
352
+ definition.inverseName = inverseDefinition.name;
353
+ definition.inverseType = inverseDefinition.type;
354
+ definition.inverseIsAsync = inverseDefinition.isAsync;
355
+ definition.inverseIsCollection = inverseDefinition.isCollection;
356
+ definition.inverseIsPolymorphic = inverseDefinition.isPolymorphic;
357
+ definition.inverseIsImplicit = inverseDefinition.isImplicit;
358
+ definition.inverseIsLinksMode = inverseDefinition.isLinksMode;
359
+ const resetOnRemoteUpdate = definition.resetOnRemoteUpdate === false || inverseDefinition.resetOnRemoteUpdate === false ? false : true;
360
+ definition.resetOnRemoteUpdate = resetOnRemoteUpdate;
361
+ inverseDefinition.resetOnRemoteUpdate = resetOnRemoteUpdate;
362
+ }
363
+ function upgradeMeta(meta) {
364
+ if (!isLegacyField(meta)) {
365
+ meta = temporaryConvertToLegacy(meta);
366
+ }
367
+ const niceMeta = {};
368
+ const options = meta.options;
369
+ niceMeta.kind = meta.kind;
370
+ niceMeta.key = meta.sourceKey ?? meta.name;
371
+ niceMeta.name = meta.name;
372
+ niceMeta.type = meta.type;
373
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
374
+ if (!test) {
375
+ throw new Error(`Expected relationship definition to specify async`);
376
+ }
377
+ })(typeof options?.async === 'boolean') : {};
378
+ niceMeta.isAsync = options.async;
379
+ niceMeta.isImplicit = false;
380
+ niceMeta.isCollection = meta.kind === 'hasMany';
381
+ niceMeta.isPolymorphic = options && !!options.polymorphic;
382
+ niceMeta.isLinksMode = options.linksMode ?? false;
383
+ niceMeta.inverseKey = options && options.inverse || STR_LATER;
384
+ niceMeta.inverseName = options && options.inverse || STR_LATER;
385
+ niceMeta.inverseType = STR_LATER;
386
+ niceMeta.inverseIsAsync = BOOL_LATER;
387
+ niceMeta.inverseIsImplicit = options && options.inverse === null || BOOL_LATER;
388
+ niceMeta.inverseIsCollection = BOOL_LATER;
389
+ niceMeta.inverseIsLinksMode = BOOL_LATER;
390
+
391
+ // prettier-ignore
392
+ niceMeta.resetOnRemoteUpdate = !isLegacyField(meta) ? false : meta.options?.linksMode ? false : meta.options?.resetOnRemoteUpdate === false ? false : true;
393
+ return niceMeta;
394
+ }
395
+ function assertConfiguration(info, type, key) {
396
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
397
+ const isSelfReferential = info.isSelfReferential;
398
+ if (isSelfReferential) {
399
+ return true;
400
+ }
401
+ const _isRHS = key === info.rhs_relationshipName && (type === info.rhs_baseModelName ||
402
+ // base or non-polymorphic
403
+ // if the other side is polymorphic then we need to scan our modelNames
404
+ info.lhs_isPolymorphic && info.rhs_modelNames.includes(type)); // polymorphic
405
+ const _isLHS = key === info.lhs_relationshipName && (type === info.lhs_baseModelName ||
406
+ // base or non-polymorphic
407
+ // if the other side is polymorphic then we need to scan our modelNames
408
+ info.rhs_isPolymorphic && info.lhs_modelNames.includes(type)); // polymorphic;
409
+
410
+ if (!_isRHS && !_isLHS) {
411
+ /*
412
+ this occurs when we are likely polymorphic but not configured to be polymorphic
413
+ most often due to extending a class that has a relationship definition on it.
414
+ e.g.
415
+ ```ts
416
+ class Pet extends Model {
417
+ @belongsTo('human', { async: false, inverse: 'pet' }) owner;
418
+ }
419
+ class Human extends Model {
420
+ @belongsTo('pet', { async: false, inverse: 'owner' }) pet;
421
+ }
422
+ class Farmer extends Human {}
423
+ ```
424
+ In the above case, the following would trigger this error:
425
+ ```ts
426
+ let pet = store.createRecord('pet');
427
+ let farmer = store.createRecord('farmer');
428
+ farmer.pet = pet; // error
429
+ ```
430
+ The correct way to fix this is to specify the polymorphic option on Pet
431
+ and to specify the abstract type 'human' on the Human base class.
432
+ ```ts
433
+ class Pet extends Model {
434
+ @belongsTo('human', { async: false, inverse: 'pet', polymorphic: true }) owner;
435
+ }
436
+ class Human extends Model {
437
+ @belongsTo('pet', { async: false, inverse: 'owner', as: 'human' }) pet;
438
+ }
439
+ class Farmer extends Human {}
440
+ ```
441
+ Alternatively both Human and Farmer could declare the relationship, because relationship
442
+ definitions are "structural".
443
+ ```ts
444
+ class Pet extends Model {
445
+ @belongsTo('human', { async: false, inverse: 'pet', polymorphic: true }) owner;
446
+ }
447
+ class Human extends Model {
448
+ @belongsTo('pet', { async: false, inverse: 'owner', as: 'human' }) pet;
449
+ }
450
+ class Farmer extends Model {
451
+ @belongsTo('pet', { async: false, inverse: 'owner', as: 'human' }) pet;
452
+ }
453
+ ```
454
+ */
455
+ if (key === info.lhs_relationshipName && info.lhs_modelNames.includes(type)) {
456
+ // parentIdentifier, parentDefinition, addedIdentifier, store
457
+ assertInheritedSchema(info.lhs_definition, type);
458
+ } else if (key === info.rhs_relationshipName && info.rhs_modelNames.includes(type)) {
459
+ assertInheritedSchema(info.lhs_definition, type);
460
+ }
461
+ // OPEN AN ISSUE :: we would like to improve our errors but need to understand what corner case got us here
462
+ throw new Error(`PLEASE OPEN AN ISSUE :: Found a relationship that is neither the LHS nor RHS of the same edge. This is not supported. Please report this to the WarpDrive team.`);
463
+ }
464
+ if (_isRHS && _isLHS) {
465
+ // not sure how we get here but it's probably the result of some form of inheritance
466
+ // without having specified polymorphism correctly leading to it not being self-referential
467
+ // OPEN AN ISSUE :: we would like to improve our errors but need to understand what corner case got us here
468
+ throw new Error(`PLEASE OPEN AN ISSUE :: Found a relationship that is both the LHS and RHS of the same edge but is not self-referential. This is not supported. Please report this to the WarpDrive team.`);
469
+ }
470
+ }
471
+ }
472
+ function isLHS(info, type, key) {
473
+ const isSelfReferential = info.isSelfReferential;
474
+ const isRelationship = key === info.lhs_relationshipName;
475
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
476
+ assertConfiguration(info, type, key);
477
+ }
478
+ if (isRelationship === true) {
479
+ return isSelfReferential === true ||
480
+ // itself
481
+ type === info.lhs_baseModelName ||
482
+ // base or non-polymorphic
483
+ // if the other side is polymorphic then we need to scan our modelNames
484
+ info.rhs_isPolymorphic && info.lhs_modelNames.includes(type) // polymorphic
485
+ ;
486
+ }
487
+ return false;
488
+ }
489
+ function upgradeDefinition(graph, key, propertyName, isImplicit = false) {
490
+ const cache = graph._definitionCache;
491
+ const storeWrapper = graph.store;
492
+ const polymorphicLookup = graph._potentialPolymorphicTypes;
493
+ const {
494
+ type
495
+ } = key;
496
+ let cached = /*#__NOINLINE__*/expandingGet(cache, type, propertyName);
497
+
498
+ // CASE: We have a cached resolution (null if no relationship exists)
499
+ if (cached !== undefined) {
500
+ return cached;
501
+ }
502
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
503
+ if (!test) {
504
+ throw new Error(`Expected to find relationship definition in the cache for the implicit relationship ${propertyName}`);
505
+ }
506
+ })(!isImplicit) : {};
507
+ const relationships = storeWrapper.schema.fields(key);
508
+ const relationshipsBySourceKey = storeWrapper.schema.cacheFields?.(key) ?? relationships;
509
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
510
+ if (!test) {
511
+ throw new Error(`Expected to have a relationship definition for ${type} but none was found.`);
512
+ }
513
+ })(relationships) : {};
514
+ const meta = relationshipsBySourceKey.get(propertyName);
515
+ if (!meta) {
516
+ // TODO potentially we should just be permissive here since this is an implicit relationship
517
+ // and not require the lookup table to be populated
518
+ if (polymorphicLookup[type]) {
519
+ const altTypes = Object.keys(polymorphicLookup[type]);
520
+ for (let i = 0; i < altTypes.length; i++) {
521
+ const _cached = expandingGet(cache, altTypes[i], propertyName);
522
+ if (_cached) {
523
+ /*#__NOINLINE__*/expandingSet(cache, type, propertyName, _cached);
524
+ _cached.rhs_modelNames.push(type);
525
+ return _cached;
526
+ }
527
+ }
528
+ }
529
+
530
+ // CASE: We don't have a relationship at all
531
+ // we should only hit this in prod
532
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
533
+ if (!test) {
534
+ throw new Error(`Expected a relationship schema for '${type}.${propertyName}', but no relationship schema was found.`);
535
+ }
536
+ })(meta) : {};
537
+ cache[type][propertyName] = null;
538
+ return null;
539
+ }
540
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
541
+ if (!test) {
542
+ throw new Error(`Expected ${propertyName} to be a relationship`);
543
+ }
544
+ })(isRelationshipField(meta)) : {};
545
+ const definition = /*#__NOINLINE__*/upgradeMeta(meta);
546
+ let inverseDefinition;
547
+ let inverseKey;
548
+ const inverseType = definition.type;
549
+
550
+ // CASE: Inverse is explicitly null
551
+ if (definition.inverseKey === null) {
552
+ // TODO probably dont need this assertion if polymorphic
553
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
554
+ if (!test) {
555
+ throw new Error(`Expected the inverse model to exist`);
556
+ }
557
+ })(getStore(storeWrapper).modelFor(inverseType)) : {};
558
+ inverseDefinition = null;
559
+ } else {
560
+ inverseKey = /*#__NOINLINE__*/inverseForRelationship(getStore(storeWrapper), key, propertyName);
561
+
562
+ // CASE: If we are polymorphic, and we declared an inverse that is non-null
563
+ // we must assume that the lack of inverseKey means that there is no
564
+ // concrete type as the baseType, so we must construct and artificial
565
+ // placeholder
566
+ if (!inverseKey && definition.isPolymorphic && definition.inverseKey) {
567
+ inverseDefinition = {
568
+ kind: 'belongsTo',
569
+ // this must be updated when we find the first belongsTo or hasMany definition that matches
570
+ key: definition.inverseKey,
571
+ name: definition.inverseName,
572
+ type: type,
573
+ isAsync: false,
574
+ // this must be updated when we find the first belongsTo or hasMany definition that matches
575
+ isImplicit: false,
576
+ isCollection: false,
577
+ // this must be updated when we find the first belongsTo or hasMany definition that matches
578
+ isPolymorphic: false
579
+ }; // the rest of the fields are populated by syncMeta
580
+
581
+ // CASE: Inverse resolves to null
582
+ } else if (!inverseKey) {
583
+ inverseDefinition = null;
584
+ } else {
585
+ // CASE: We have an explicit inverse or were able to resolve one
586
+ // for the inverse we use "name" for lookup not "sourceKey"
587
+ const inverseDefinitions = storeWrapper.schema.fields({
588
+ type: inverseType
589
+ });
590
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
591
+ if (!test) {
592
+ throw new Error(`Expected to have a relationship definition for ${inverseType} but none was found.`);
593
+ }
594
+ })(inverseDefinitions) : {};
595
+ const metaFromInverse = inverseDefinitions.get(inverseKey);
596
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
597
+ if (!test) {
598
+ throw new Error(`Expected a relationship schema for '${inverseType}.${inverseKey}' to match the inverse of '${type}.${propertyName}', but no relationship schema was found.`);
599
+ }
600
+ })(metaFromInverse) : {};
601
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
602
+ if (!test) {
603
+ throw new Error(`Expected ${inverseKey} to be a relationship`);
604
+ }
605
+ })(isRelationshipField(metaFromInverse)) : {};
606
+ inverseDefinition = upgradeMeta(metaFromInverse);
607
+ }
608
+ }
609
+
610
+ // CASE: We have no inverse
611
+ if (!inverseDefinition) {
612
+ // polish off meta
613
+ inverseKey = /*#__NOINLINE__*/implicitKeyFor(type, propertyName);
614
+ inverseDefinition = {
615
+ kind: 'implicit',
616
+ key: inverseKey,
617
+ type: type,
618
+ isAsync: false,
619
+ isImplicit: true,
620
+ isCollection: true,
621
+ // with implicits any number of records could point at us
622
+ isPolymorphic: false
623
+ }; // the rest of the fields are populated by syncMeta
624
+
625
+ syncMeta(definition, inverseDefinition);
626
+ syncMeta(inverseDefinition, definition);
627
+ const info = {
628
+ lhs_key: `${type}:${propertyName}`,
629
+ lhs_modelNames: [type],
630
+ lhs_baseModelName: type,
631
+ lhs_relationshipName: propertyName,
632
+ lhs_definition: definition,
633
+ lhs_isPolymorphic: definition.isPolymorphic,
634
+ rhs_key: inverseDefinition.key,
635
+ rhs_modelNames: [inverseType],
636
+ rhs_baseModelName: inverseType,
637
+ rhs_relationshipName: inverseDefinition.key,
638
+ rhs_definition: inverseDefinition,
639
+ rhs_isPolymorphic: false,
640
+ hasInverse: false,
641
+ isSelfReferential: type === inverseType,
642
+ // this could be wrong if we are self-referential but also polymorphic
643
+ isReflexive: false // we can't be reflexive if we don't define an inverse
644
+ };
645
+ expandingSet(cache, inverseType, inverseKey, info);
646
+ expandingSet(cache, type, propertyName, info);
647
+ return info;
648
+ }
649
+
650
+ // CASE: We do have an inverse
651
+ const baseType = inverseDefinition.type;
652
+
653
+ // TODO we want to assert this but this breaks all of our shoddily written tests
654
+ /*
655
+ if (DEBUG) {
656
+ let inverseDoubleCheck = inverseFor(inverseRelationshipName, store);
657
+ assert(`The ${inverseBaseModelName}:${inverseRelationshipName} relationship declares 'inverse: null', but it was resolved as the inverse for ${baseModelName}:${relationshipName}.`, inverseDoubleCheck);
658
+ }
659
+ */
660
+ // CASE: We may have already discovered the inverse for the baseModelName
661
+ // CASE: We have already discovered the inverse
662
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
663
+ if (!test) {
664
+ throw new Error(`We should have determined an inverseKey by now, open an issue if this is hit`);
665
+ }
666
+ })(typeof inverseKey === 'string' && inverseKey.length > 0) : {};
667
+ cached = expandingGet(cache, baseType, propertyName) || expandingGet(cache, inverseType, inverseKey);
668
+ if (cached) {
669
+ // TODO this assert can be removed if the above assert is enabled
670
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
671
+ if (!test) {
672
+ throw new Error(`The ${inverseType}:${inverseKey} relationship declares 'inverse: null', but it was resolved as the inverse for ${type}:${propertyName}.`);
673
+ }
674
+ })(cached.hasInverse !== false) : {};
675
+ const _isLHS = cached.lhs_baseModelName === baseType;
676
+ const modelNames = _isLHS ? cached.lhs_modelNames : cached.rhs_modelNames;
677
+ // make this lookup easier in the future by caching the key
678
+ modelNames.push(type);
679
+ expandingSet(cache, type, propertyName, cached);
680
+ return cached;
681
+ }
682
+
683
+ // this is our first time so polish off the metas
684
+ syncMeta(definition, inverseDefinition);
685
+ syncMeta(inverseDefinition, definition);
686
+ const lhs_modelNames = [type];
687
+ if (type !== baseType) {
688
+ lhs_modelNames.push(baseType);
689
+ }
690
+ const isSelfReferential = baseType === inverseType;
691
+ const info = {
692
+ lhs_key: `${baseType}:${propertyName}`,
693
+ lhs_modelNames,
694
+ lhs_baseModelName: baseType,
695
+ lhs_relationshipName: propertyName,
696
+ lhs_definition: definition,
697
+ lhs_isPolymorphic: definition.isPolymorphic,
698
+ rhs_key: `${inverseType}:${inverseKey}`,
699
+ rhs_modelNames: [inverseType],
700
+ rhs_baseModelName: inverseType,
701
+ rhs_relationshipName: inverseKey,
702
+ rhs_definition: inverseDefinition,
703
+ rhs_isPolymorphic: inverseDefinition.isPolymorphic,
704
+ hasInverse: true,
705
+ isSelfReferential,
706
+ isReflexive: isSelfReferential && propertyName === inverseKey
707
+ };
708
+
709
+ // Create entries for the baseModelName as well as modelName to speed up
710
+ // inverse lookups
711
+ expandingSet(cache, baseType, propertyName, info);
712
+ expandingSet(cache, type, propertyName, info);
713
+
714
+ // Greedily populate the inverse
715
+ expandingSet(cache, inverseType, inverseKey, info);
716
+ return info;
717
+ }
718
+ function inverseForRelationship(store, resourceKey, key) {
719
+ const fields = store.schema.fields(resourceKey);
720
+ const definition = fields.get(key);
721
+ if (!definition) {
722
+ return null;
723
+ }
724
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
725
+ if (!test) {
726
+ throw new Error(`Expected ${key} to be a relationship`);
727
+ }
728
+ })(isRelationshipField(definition)) : {};
729
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
730
+ if (!test) {
731
+ throw new Error(`Expected the relationship defintion to specify the inverse type or null.`);
732
+ }
733
+ })(definition.options?.inverse === null || typeof definition.options?.inverse === 'string' && definition.options.inverse.length > 0) : {};
734
+ return definition.options.inverse;
735
+ }
736
+
737
+ /* eslint-disable @typescript-eslint/no-shadow */
738
+
739
+ let assertPolymorphicType;
740
+ let assertInheritedSchema;
741
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
742
+ function validateSchema(definition, meta) {
743
+ const errors = new Map();
744
+ if (definition.inverseKey !== meta.name) {
745
+ errors.set('name', ` <---- should be '${definition.inverseKey}'`);
746
+ }
747
+ if (definition.inverseType !== meta.type) {
748
+ errors.set('type', ` <---- should be '${definition.inverseType}'`);
749
+ }
750
+ if (definition.inverseKind !== meta.kind) {
751
+ errors.set('type', ` <---- should be '${definition.inverseKind}'`);
752
+ }
753
+ if (definition.inverseIsAsync !== meta.options.async) {
754
+ errors.set('async', ` <---- should be ${definition.inverseIsAsync}`);
755
+ }
756
+ if (definition.inverseIsPolymorphic && definition.inverseIsPolymorphic !== meta.options.polymorphic) {
757
+ errors.set('polymorphic', ` <---- should be ${definition.inverseIsPolymorphic}`);
758
+ }
759
+ if (definition.key !== meta.options.inverse) {
760
+ errors.set('inverse', ` <---- should be '${definition.key}'`);
761
+ }
762
+ if (definition.type !== meta.options.as) {
763
+ errors.set('as', ` <---- should be '${definition.type}'`);
764
+ }
765
+ return errors;
766
+ }
767
+ function expectedSchema(definition) {
768
+ return printSchema({
769
+ name: definition.inverseKey,
770
+ type: definition.inverseType,
771
+ kind: definition.inverseKind,
772
+ options: {
773
+ as: definition.type,
774
+ async: definition.inverseIsAsync,
775
+ polymorphic: definition.inverseIsPolymorphic || false,
776
+ inverse: definition.key
777
+ }
778
+ });
779
+ }
780
+ function printSchema(config, errors) {
781
+ return `
782
+
783
+ \`\`\`
784
+ {
785
+ ${config.name}: {
786
+ name: '${config.name}',${errors?.get('name') || ''}
787
+ type: '${config.type}',${errors?.get('type') || ''}
788
+ kind: '${config.kind}',${errors?.get('kind') || ''}
789
+ options: {
790
+ as: '${config.options.as}',${errors?.get('as') || ''}
791
+ async: ${config.options.async},${errors?.get('async') || ''}
792
+ polymorphic: ${config.options.polymorphic},${errors?.get('polymorphic') || ''}
793
+ inverse: '${config.options.inverse}'${errors?.get('inverse') || ''}
794
+ }
795
+ }
796
+ }
797
+ \`\`\`
798
+
799
+ `;
800
+ }
801
+ function metaFrom(definition) {
802
+ return {
803
+ name: definition.key,
804
+ type: definition.type,
805
+ kind: definition.kind,
806
+ options: {
807
+ async: definition.isAsync,
808
+ polymorphic: definition.isPolymorphic,
809
+ inverse: definition.inverseKey
810
+ }
811
+ };
812
+ }
813
+ function inverseMetaFrom(definition) {
814
+ return {
815
+ name: definition.inverseKey,
816
+ type: definition.inverseType,
817
+ kind: definition.inverseKind,
818
+ options: {
819
+ as: definition.isPolymorphic ? definition.type : undefined,
820
+ async: definition.inverseIsAsync,
821
+ polymorphic: definition.inverseIsPolymorphic,
822
+ inverse: definition.key
823
+ }
824
+ };
825
+ }
826
+ function inverseDefinition(definition) {
827
+ return {
828
+ key: definition.inverseKey,
829
+ name: definition.inverseName,
830
+ type: definition.inverseType,
831
+ kind: definition.inverseKind,
832
+ isAsync: definition.inverseIsAsync,
833
+ isPolymorphic: true,
834
+ isLinksMode: definition.isLinksMode,
835
+ isCollection: definition.inverseIsCollection,
836
+ isImplicit: definition.inverseIsImplicit,
837
+ inverseKey: definition.key,
838
+ inverseName: definition.name,
839
+ inverseType: definition.type,
840
+ inverseKind: definition.kind,
841
+ inverseIsAsync: definition.isAsync,
842
+ inverseIsPolymorphic: definition.isPolymorphic,
843
+ inverseIsLinksMode: definition.inverseIsLinksMode,
844
+ inverseIsImplicit: definition.isImplicit,
845
+ inverseIsCollection: definition.isCollection,
846
+ resetOnRemoteUpdate: definition.resetOnRemoteUpdate
847
+ };
848
+ }
849
+ function definitionWithPolymorphic(definition) {
850
+ return Object.assign({}, definition, {
851
+ inverseIsPolymorphic: true
852
+ });
853
+ }
854
+ assertInheritedSchema = function assertInheritedSchema(definition, type) {
855
+ const meta1 = metaFrom(definition);
856
+ const meta2 = inverseMetaFrom(definition);
857
+ const errors1 = validateSchema(inverseDefinition(definition), meta1);
858
+ const errors2 = validateSchema(definitionWithPolymorphic(definition), meta2);
859
+ if (errors2.size === 0 && errors1.size > 0) {
860
+ throw new Error(`The schema for the relationship '${type}.${definition.key}' is not configured to satisfy '${definition.inverseType}' and thus cannot utilize the '${definition.inverseType}.${definition.key}' relationship to connect with '${definition.type}.${definition.inverseKey}'\n\nIf using this relationship in a polymorphic manner is desired, the relationships schema definition for '${type}' should include:${printSchema(meta1, errors1)}`);
861
+ } else if (errors1.size > 0) {
862
+ throw new Error(`The schema for the relationship '${type}.${definition.key}' is not configured to satisfy '${definition.inverseType}' and thus cannot utilize the '${definition.inverseType}.${definition.key}' relationship to connect with '${definition.type}.${definition.inverseKey}'\n\nIf using this relationship in a polymorphic manner is desired, the relationships schema definition for '${type}' should include:${printSchema(meta1, errors1)} and the relationships schema definition for '${definition.type}' should include:${printSchema(meta2, errors2)}`);
863
+ } else if (errors2.size > 0) {
864
+ throw new Error(`The schema for the relationship '${type}.${definition.key}' satisfies '${definition.inverseType}' but cannot utilize the '${definition.inverseType}.${definition.key}' relationship to connect with '${definition.type}.${definition.inverseKey}' because that relationship is not polymorphic.\n\nIf using this relationship in a polymorphic manner is desired, the relationships schema definition for '${definition.type}' should include:${printSchema(meta2, errors2)}`);
865
+ }
866
+ };
867
+ assertPolymorphicType = function assertPolymorphicType(parentIdentifier, parentDefinition, addedIdentifier, store) {
868
+ if (parentDefinition.inverseIsImplicit) {
869
+ return;
870
+ }
871
+ if (parentDefinition.isPolymorphic) {
872
+ let meta = store.schema.fields(addedIdentifier).get(parentDefinition.inverseKey);
873
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
874
+ if (!test) {
875
+ throw new Error(`No '${parentDefinition.inverseKey}' field exists on '${addedIdentifier.type}'. To use this type in the polymorphic relationship '${parentDefinition.inverseType}.${parentDefinition.key}' the relationships schema definition for ${addedIdentifier.type} should include:${expectedSchema(parentDefinition)}`);
876
+ }
877
+ })(meta) : {};
878
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
879
+ if (!test) {
880
+ throw new Error(`Expected the field ${parentDefinition.inverseKey} to be a relationship`);
881
+ }
882
+ })(meta && isRelationshipField(meta)) : {};
883
+ meta = isLegacyField(meta) ? meta : temporaryConvertToLegacy(meta);
884
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
885
+ if (!test) {
886
+ throw new Error(`You should not specify both options.as and options.inverse as null on ${addedIdentifier.type}.${parentDefinition.inverseKey}, as if there is no inverse field there is no abstract type to conform to. You may have intended for this relationship to be polymorphic, or you may have mistakenly set inverse to null.`);
887
+ }
888
+ })(!(meta.options.inverse === null && meta?.options.as?.length)) : {};
889
+ const errors = validateSchema(parentDefinition, meta);
890
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
891
+ if (!test) {
892
+ throw new Error(`The schema for the relationship '${parentDefinition.inverseKey}' on '${addedIdentifier.type}' type does not correctly implement '${parentDefinition.type}' and thus cannot be assigned to the '${parentDefinition.key}' relationship in '${parentIdentifier.type}'. If using this record in this polymorphic relationship is desired, correct the errors in the schema shown below:${printSchema(meta, errors)}`);
893
+ }
894
+ })(errors.size === 0) : {};
895
+ } else if (addedIdentifier.type !== parentDefinition.type) {
896
+ // if we are not polymorphic
897
+ // then the addedIdentifier.type must be the same as the parentDefinition.type
898
+ let meta = store.schema.fields(addedIdentifier).get(parentDefinition.inverseKey);
899
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
900
+ if (!test) {
901
+ throw new Error(`Expected the field ${parentDefinition.inverseKey} to be a relationship`);
902
+ }
903
+ })(!meta || isRelationshipField(meta)) : {};
904
+ meta = meta && (isLegacyField(meta) ? meta : temporaryConvertToLegacy(meta));
905
+ if (meta?.options.as === parentDefinition.type) {
906
+ // inverse is likely polymorphic but missing the polymorphic flag
907
+ let meta = store.schema.fields({
908
+ type: parentDefinition.inverseType
909
+ }).get(parentDefinition.key);
910
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
911
+ if (!test) {
912
+ throw new Error(`Expected the field ${parentDefinition.key} to be a relationship`);
913
+ }
914
+ })(meta && isRelationshipField(meta)) : {};
915
+ meta = isLegacyField(meta) ? meta : temporaryConvertToLegacy(meta);
916
+ const errors = validateSchema(definitionWithPolymorphic(inverseDefinition(parentDefinition)), meta);
917
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
918
+ {
919
+ throw new Error(`The '<${addedIdentifier.type}>.${parentDefinition.inverseKey}' relationship cannot be used polymorphically because '<${parentDefinition.inverseType}>.${parentDefinition.key} is not a polymorphic relationship. To use this relationship in a polymorphic manner, fix the following schema issues on the relationships schema for '${parentDefinition.inverseType}':${printSchema(meta, errors)}`);
920
+ }
921
+ })() : {};
922
+ } else {
923
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
924
+ {
925
+ throw new Error(`The '${addedIdentifier.type}' type does not implement '${parentDefinition.type}' and thus cannot be assigned to the '${parentDefinition.key}' relationship in '${parentIdentifier.type}'. If this relationship should be polymorphic, mark ${parentDefinition.inverseType}.${parentDefinition.key} as \`polymorphic: true\` and ${addedIdentifier.type}.${parentDefinition.inverseKey} as implementing it via \`as: '${parentDefinition.type}'\`.`);
926
+ }
927
+ })() : {};
928
+ }
929
+ }
930
+ };
931
+ }
932
+ function count(label) {
933
+ // @ts-expect-error
934
+ // eslint-disable-next-line
935
+ globalThis.__WarpDriveMetricCountData[label] = (globalThis.__WarpDriveMetricCountData[label] || 0) + 1;
936
+ }
937
+
938
+ /*
939
+ case many:1
940
+ ========
941
+ In a bi-directional graph with Many:1 edges, adding a value
942
+ results in up-to 3 discrete value transitions, while removing
943
+ a value is only 2 transitions.
944
+
945
+ For adding C to A
946
+ If: A <<-> B, C <->> D is the initial state,
947
+ and: B <->> A <<-> C, D is the final state
948
+
949
+ then we would undergo the following transitions.
950
+
951
+ add C to A
952
+ remove C from D
953
+ add A to C
954
+
955
+ For removing B from A
956
+ If: A <<-> B, C <->> D is the initial state,
957
+ and: A, B, C <->> D is the final state
958
+
959
+ then we would undergo the following transitions.
960
+
961
+ remove B from A
962
+ remove A from B
963
+
964
+ case many:many
965
+ ===========
966
+ In a bi-directional graph with Many:Many edges, adding or
967
+ removing a value requires only 2 value transitions.
968
+
969
+ For Adding
970
+ If: A<<->>B, C<<->>D is the initial state (double arrows representing the many side)
971
+ And: D<<->>C<<->>A<<->>B is the final state
972
+
973
+ Then we would undergo two transitions.
974
+
975
+ add C to A.
976
+ add A to C
977
+
978
+ For Removing
979
+ If: A<<->>B, C<<->>D is the initial state (double arrows representing the many side)
980
+ And: A, B, C<<->>D is the final state
981
+
982
+ Then we would undergo two transitions.
983
+
984
+ remove B from A
985
+ remove A from B
986
+
987
+ case many:?
988
+ ========
989
+ In a uni-directional graph with Many:? edges (modeled in WarpDrive with `inverse:null`) with
990
+ artificial (implicit) inverses, replacing a value results in 2 discrete value transitions.
991
+ This is because a Many:? relationship is effectively Many:Many.
992
+ */
993
+ function replaceRelatedRecords(graph, op, isRemote) {
994
+ if (isRemote) {
995
+ replaceRelatedRecordsRemote(graph, op, isRemote);
996
+ } else {
997
+ replaceRelatedRecordsLocal(graph, op, isRemote);
998
+ }
999
+ }
1000
+ function replaceRelatedRecordsLocal(graph, op, isRemote) {
1001
+ const resourceKeys = op.value;
1002
+ const relationship = graph.get(op.record, op.field);
1003
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1004
+ if (!test) {
1005
+ throw new Error(`expected hasMany relationship`);
1006
+ }
1007
+ })(isHasMany(relationship)) : {};
1008
+ relationship.state.hasReceivedData = true;
1009
+ const {
1010
+ additions,
1011
+ removals
1012
+ } = relationship;
1013
+ const {
1014
+ inverseKey,
1015
+ type
1016
+ } = relationship.definition;
1017
+ const {
1018
+ record
1019
+ } = op;
1020
+ const wasDirty = relationship.isDirty;
1021
+ let localBecameDirty = false;
1022
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
1023
+ if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
1024
+ count(`replaceRelatedRecordsLocal ${'type' in record ? record.type : '<document>'} ${op.field}`);
1025
+ }
1026
+ }
1027
+ const onAdd = resourceKey => {
1028
+ // Since we are diffing against the remote state, we check
1029
+ // if our previous local state did not contain this ResourceKey
1030
+ const removalsHas = removals?.has(resourceKey);
1031
+ if (removalsHas || !additions?.has(resourceKey)) {
1032
+ if (type !== resourceKey.type) {
1033
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
1034
+ assertPolymorphicType(relationship.identifier, relationship.definition, resourceKey, graph.store);
1035
+ }
1036
+ graph.registerPolymorphicType(type, resourceKey.type);
1037
+ }
1038
+
1039
+ // we've added a record locally that wasn't in the local state before
1040
+ localBecameDirty = true;
1041
+ addToInverse(graph, resourceKey, inverseKey, op.record, isRemote);
1042
+ if (removalsHas) {
1043
+ removals.delete(resourceKey);
1044
+ }
1045
+ }
1046
+ };
1047
+ const onRemove = resourceKey => {
1048
+ // Since we are diffing against the remote state, we check
1049
+ // if our previous local state had contained this ResourceKey
1050
+ const additionsHas = additions?.has(resourceKey);
1051
+ if (additionsHas || !removals?.has(resourceKey)) {
1052
+ // we've removed a record locally that was in the local state before
1053
+ localBecameDirty = true;
1054
+ removeFromInverse(graph, resourceKey, inverseKey, record, isRemote);
1055
+ if (additionsHas) {
1056
+ additions.delete(resourceKey);
1057
+ }
1058
+ }
1059
+ };
1060
+ const diff = diffCollection(resourceKeys, relationship, onAdd, onRemove);
1061
+
1062
+ // any additions no longer in the local state
1063
+ // also need to be removed from the inverse
1064
+ if (additions && additions.size > 0) {
1065
+ additions.forEach(resourceKey => {
1066
+ if (!diff.add.has(resourceKey)) {
1067
+ localBecameDirty = true;
1068
+ onRemove(resourceKey);
1069
+ }
1070
+ });
1071
+ }
1072
+
1073
+ // any removals no longer in the local state
1074
+ // also need to be added back to the inverse
1075
+ if (removals && removals.size > 0) {
1076
+ removals.forEach(resourceKey => {
1077
+ if (!diff.del.has(resourceKey)) {
1078
+ localBecameDirty = true;
1079
+ onAdd(resourceKey);
1080
+ }
1081
+ });
1082
+ }
1083
+ const becameDirty = diff.changed || localBecameDirty;
1084
+ relationship.additions = diff.add;
1085
+ relationship.removals = diff.del;
1086
+ relationship.localState = diff.finalState;
1087
+
1088
+ // we only notify if the localState changed and were not already dirty before
1089
+ // because if we were already dirty then we have already notified
1090
+ if (becameDirty && !wasDirty) {
1091
+ notifyChange(graph, relationship);
1092
+ }
1093
+ }
1094
+ function replaceRelatedRecordsRemote(graph, op, isRemote) {
1095
+ const resourceKeys = op.value;
1096
+ const relationship = graph.get(op.record, op.field);
1097
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
1098
+ if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
1099
+ count(`replaceRelatedRecordsRemote ${'type' in op.record ? op.record.type : '<document>'} ${op.field}`);
1100
+ }
1101
+ }
1102
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1103
+ if (!test) {
1104
+ throw new Error(`You can only '${op.op}' on a hasMany relationship. ${op.record.type}.${op.field} is a ${relationship.definition.kind}`);
1105
+ }
1106
+ })(isHasMany(relationship)) : {};
1107
+ if (isRemote) {
1108
+ graph._addToTransaction(relationship);
1109
+ }
1110
+ const wasDirty = relationship.isDirty;
1111
+ // if this is our first time receiving data
1112
+ // we need to mark the relationship as dirty
1113
+ // so that non-materializing APIs like `hasManyReference.value()`
1114
+ // will get notified and updated.
1115
+ if (!relationship.state.hasReceivedData) {
1116
+ relationship.isDirty = true;
1117
+ }
1118
+ relationship.state.hasReceivedData = true;
1119
+
1120
+ // cache existing state
1121
+ const {
1122
+ definition
1123
+ } = relationship;
1124
+ const {
1125
+ type
1126
+ } = relationship.definition;
1127
+ const diff = diffCollection(resourceKeys, relationship, resourceKey => {
1128
+ if (type !== resourceKey.type) {
1129
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
1130
+ assertPolymorphicType(relationship.identifier, relationship.definition, resourceKey, graph.store);
1131
+ }
1132
+ graph.registerPolymorphicType(type, resourceKey.type);
1133
+ }
1134
+ // commit additions
1135
+ // TODO build this into the diff?
1136
+ // because we are not dirty if this was a committed local addition
1137
+ if (relationship.additions?.has(resourceKey)) {
1138
+ relationship.additions.delete(resourceKey);
1139
+ } else {
1140
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.DEBUG_RELATIONSHIP_NOTIFICATIONS)) {
1141
+ if (getGlobalConfig().WarpDrive.debug.DEBUG_RELATIONSHIP_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.DEBUG_RELATIONSHIP_NOTIFICATIONS) {
1142
+ if (!relationship.isDirty) {
1143
+ // eslint-disable-next-line no-console
1144
+ console.log(`setting relationship to dirty because the remote addition was not in our previous list of local additions`);
1145
+ }
1146
+ }
1147
+ }
1148
+ }
1149
+ addToInverse(graph, resourceKey, definition.inverseKey, op.record, isRemote);
1150
+ }, resourceKey => {
1151
+ // commit removals
1152
+ // TODO build this into the diff?
1153
+ // because we are not dirty if this was a committed local addition
1154
+ if (relationship.removals?.has(resourceKey)) {
1155
+ relationship.removals.delete(resourceKey);
1156
+ } else {
1157
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.DEBUG_RELATIONSHIP_NOTIFICATIONS)) {
1158
+ if (getGlobalConfig().WarpDrive.debug.DEBUG_RELATIONSHIP_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.DEBUG_RELATIONSHIP_NOTIFICATIONS) {
1159
+ if (!relationship.isDirty) {
1160
+ // eslint-disable-next-line no-console
1161
+ console.log(`setting relationship to dirty because the remote removal was not in our previous list of local removals`);
1162
+ }
1163
+ }
1164
+ }
1165
+ }
1166
+ removeFromInverse(graph, resourceKey, definition.inverseKey, op.record, isRemote);
1167
+ });
1168
+
1169
+ // replace existing state
1170
+ relationship.remoteMembers = diff.finalSet;
1171
+ relationship.remoteState = diff.finalState;
1172
+
1173
+ // changed also indicates a change in order
1174
+ if (diff.changed) {
1175
+ relationship.isDirty = true;
1176
+ }
1177
+
1178
+ // TODO unsure if we need this but it
1179
+ // may allow us to more efficiently patch
1180
+ // the associated ManyArray
1181
+ relationship._diff = diff;
1182
+ if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_RELATIONSHIP_REMOTE_UPDATE_CLEARING_LOCAL_STATE)) {
1183
+ // only do this for legacy hasMany, not collection
1184
+ // and provide a way to incrementally migrate
1185
+ if (
1186
+ // we do not guard by diff.changed here
1187
+ // because we want to clear local changes even if
1188
+ // no change has occurred to preserve the legacy behavior
1189
+ relationship.definition.kind === 'hasMany' && relationship.definition.resetOnRemoteUpdate !== false && (diff.changed || wasDirty)) {
1190
+ const deprecationInfo = {
1191
+ removals: [],
1192
+ additions: [],
1193
+ triggered: false
1194
+ };
1195
+ if (relationship.removals) {
1196
+ relationship.isDirty = true;
1197
+ relationship.removals.forEach(resourceKey => {
1198
+ deprecationInfo.triggered = true;
1199
+ deprecationInfo.removals.push(resourceKey);
1200
+ // reverse the removal
1201
+ // if we are still in removals at this point then
1202
+ // we were not "committed" which means we are present
1203
+ // in the remoteMembers. So we "add back" on the inverse.
1204
+ addToInverse(graph, resourceKey, definition.inverseKey, op.record, false);
1205
+ });
1206
+ relationship.removals = null;
1207
+ }
1208
+ if (relationship.additions) {
1209
+ relationship.additions.forEach(resourceKey => {
1210
+ // reverse the addition
1211
+ // if we are still in additions at this point then
1212
+ // we were not "committed" which means we are not present
1213
+ // in the remoteMembers. So we "remove" from the inverse.
1214
+ // however we only do this if we are not a "new" record.
1215
+ if (!checkIfNew(graph._realStore, resourceKey)) {
1216
+ deprecationInfo.triggered = true;
1217
+ deprecationInfo.additions.push(resourceKey);
1218
+ relationship.isDirty = true;
1219
+ relationship.additions.delete(resourceKey);
1220
+ removeFromInverse(graph, resourceKey, definition.inverseKey, op.record, false);
1221
+ }
1222
+ });
1223
+ if (relationship.additions.size === 0) {
1224
+ relationship.additions = null;
1225
+ }
1226
+ }
1227
+ if (deprecationInfo.triggered) {
1228
+ deprecate(`WarpDrive is changing the default semantics of updates to the remote state of relationships.\n\nThe following local state was cleared from the <${relationship.identifier.type}>.${relationship.definition.key} hasMany relationship but will not be once this deprecation is resolved by opting into the new behavior:\n\n\tAdded: [${deprecationInfo.additions.map(i => i.lid).join(', ')}]\n\tRemoved: [${deprecationInfo.removals.map(i => i.lid).join(', ')}]`, false, {
1229
+ id: 'ember-data:deprecate-relationship-remote-update-clearing-local-state',
1230
+ for: 'ember-data',
1231
+ since: {
1232
+ enabled: '5.3',
1233
+ available: '4.13'
1234
+ },
1235
+ until: '6.0',
1236
+ url: 'https://deprecations.emberjs.com/v5.x#ember-data-deprecate-relationship-remote-update-clearing-local-state'
1237
+ });
1238
+ }
1239
+ }
1240
+ }
1241
+ if (relationship.isDirty && !wasDirty) {
1242
+ flushCanonical(graph, relationship);
1243
+ }
1244
+ }
1245
+ function addToInverse(graph, resourceKey, key, value, isRemote) {
1246
+ const relationship = graph.get(resourceKey, key);
1247
+ const {
1248
+ type
1249
+ } = relationship.definition;
1250
+ if (type !== value.type) {
1251
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
1252
+ assertPolymorphicType(relationship.identifier, relationship.definition, value, graph.store);
1253
+ }
1254
+ graph.registerPolymorphicType(type, value.type);
1255
+ }
1256
+ if (isBelongsTo(relationship)) {
1257
+ relationship.state.hasReceivedData = true;
1258
+ relationship.state.isEmpty = false;
1259
+ if (isRemote) {
1260
+ graph._addToTransaction(relationship);
1261
+ if (relationship.remoteState !== null) {
1262
+ removeFromInverse(graph, relationship.remoteState, relationship.definition.inverseKey, resourceKey, isRemote);
1263
+ }
1264
+ relationship.remoteState = value;
1265
+ }
1266
+ if (relationship.localState !== value) {
1267
+ if (!isRemote && relationship.localState) {
1268
+ removeFromInverse(graph, relationship.localState, relationship.definition.inverseKey, resourceKey, isRemote);
1269
+ }
1270
+ relationship.localState = value;
1271
+ notifyChange(graph, relationship);
1272
+ }
1273
+ } else if (isHasMany(relationship)) {
1274
+ if (isRemote) {
1275
+ // TODO this needs to alert stuffs
1276
+ // And patch state better
1277
+ // This is almost definitely wrong
1278
+ // WARNING WARNING WARNING
1279
+
1280
+ if (!relationship.remoteMembers.has(value)) {
1281
+ graph._addToTransaction(relationship);
1282
+ relationship.remoteState.push(value);
1283
+ relationship.remoteMembers.add(value);
1284
+ if (relationship.additions?.has(value)) {
1285
+ relationship.additions.delete(value);
1286
+ } else {
1287
+ relationship.isDirty = true;
1288
+ relationship.state.hasReceivedData = true;
1289
+ flushCanonical(graph, relationship);
1290
+ }
1291
+ }
1292
+ } else {
1293
+ // if we are not dirty but have a null localState then we
1294
+ // are mutating a relationship that has never been fetched
1295
+ // so we initialize localState to an empty array
1296
+ if (!relationship.isDirty && !relationship.localState) {
1297
+ relationship.localState = [];
1298
+ }
1299
+ if (_add(graph, resourceKey, relationship, value, null, isRemote)) {
1300
+ notifyChange(graph, relationship);
1301
+ }
1302
+ }
1303
+ } else {
1304
+ if (isRemote) {
1305
+ if (!relationship.remoteMembers.has(value)) {
1306
+ relationship.remoteMembers.add(value);
1307
+ relationship.localMembers.add(value);
1308
+ }
1309
+ } else {
1310
+ if (!relationship.localMembers.has(value)) {
1311
+ relationship.localMembers.add(value);
1312
+ }
1313
+ }
1314
+ }
1315
+ }
1316
+ function notifyInverseOfPotentialMaterialization(graph, resourceKey, key, value, isRemote) {
1317
+ const relationship = graph.get(resourceKey, key);
1318
+ if (isHasMany(relationship) && isRemote && relationship.remoteMembers.has(value)) {
1319
+ notifyChange(graph, relationship);
1320
+ }
1321
+ }
1322
+ function removeFromInverse(graph, resourceKey, key, value, isRemote) {
1323
+ const relationship = graph.get(resourceKey, key);
1324
+ if (isBelongsTo(relationship)) {
1325
+ relationship.state.isEmpty = true;
1326
+ if (isRemote) {
1327
+ graph._addToTransaction(relationship);
1328
+ relationship.remoteState = null;
1329
+ }
1330
+ if (relationship.localState === value) {
1331
+ relationship.localState = null;
1332
+ notifyChange(graph, relationship);
1333
+ }
1334
+ } else if (isHasMany(relationship)) {
1335
+ if (isRemote) {
1336
+ graph._addToTransaction(relationship);
1337
+ if (_removeRemote(relationship, value)) {
1338
+ notifyChange(graph, relationship);
1339
+ }
1340
+ } else {
1341
+ if (_removeLocal(relationship, value)) {
1342
+ notifyChange(graph, relationship);
1343
+ }
1344
+ }
1345
+ } else {
1346
+ if (isRemote) {
1347
+ relationship.remoteMembers.delete(value);
1348
+ relationship.localMembers.delete(value);
1349
+ } else {
1350
+ if (value && relationship.localMembers.has(value)) {
1351
+ relationship.localMembers.delete(value);
1352
+ }
1353
+ }
1354
+ }
1355
+ }
1356
+ function flushCanonical(graph, rel) {
1357
+ if (rel.accessed) {
1358
+ graph._scheduleLocalSync(rel);
1359
+ }
1360
+ }
1361
+ function replaceRelatedRecord(graph, op, isRemote = false) {
1362
+ const relationship = graph.get(op.record, op.field);
1363
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1364
+ if (!test) {
1365
+ throw new Error(`You can only '${op.op}' on a belongsTo relationship. ${op.record.type}.${op.field} is a ${relationship.definition.kind}`);
1366
+ }
1367
+ })(isBelongsTo(relationship)) : {};
1368
+ if (isRemote) {
1369
+ graph._addToTransaction(relationship);
1370
+ }
1371
+ const {
1372
+ definition,
1373
+ state
1374
+ } = relationship;
1375
+ const prop = isRemote ? 'remoteState' : 'localState';
1376
+ const existingState = relationship[prop];
1377
+
1378
+ /*
1379
+ case 1:1
1380
+ ========
1381
+ In a bi-directional graph with 1:1 edges, replacing a value
1382
+ results in up-to 4 discrete value transitions.
1383
+ If: A <-> B, C <-> D is the initial state,
1384
+ and: A <-> C, B, D is the final state
1385
+ then we would undergo the following 4 transitions.
1386
+ remove A from B
1387
+ add C to A
1388
+ remove C from D
1389
+ add A to C
1390
+ case 1:many
1391
+ ===========
1392
+ In a bi-directional graph with 1:Many edges, replacing a value
1393
+ results in up-to 3 discrete value transitions.
1394
+ If: A<->>B<<->D, C<<->D is the initial state (double arrows representing the many side)
1395
+ And: A<->>C<<->D, B<<->D is the final state
1396
+ Then we would undergo three transitions.
1397
+ remove A from B
1398
+ add C to A.
1399
+ add A to C
1400
+ case 1:?
1401
+ ========
1402
+ In a uni-directional graph with 1:? edges (modeled in WarpDrive with `inverse:null`) with
1403
+ artificial (implicit) inverses, replacing a value results in up-to 3 discrete value transitions.
1404
+ This is because a 1:? relationship is effectively 1:many.
1405
+ If: A->B, C->B is the initial state
1406
+ And: A->C, C->B is the final state
1407
+ Then we would undergo three transitions.
1408
+ Remove A from B
1409
+ Add C to A
1410
+ Add A to C
1411
+ */
1412
+
1413
+ // nothing for us to do
1414
+ if (op.value === existingState) {
1415
+ // if we were empty before but now know we are empty this needs to be true
1416
+ state.hasReceivedData = true;
1417
+ // if this is a remote update we still sync
1418
+ if (isRemote) {
1419
+ const {
1420
+ localState
1421
+ } = relationship;
1422
+ // don't sync if localState is a new record and our remoteState is null
1423
+ if (localState && checkIfNew(graph._realStore, localState) && !existingState) {
1424
+ return;
1425
+ }
1426
+ if (existingState && localState === existingState) {
1427
+ notifyInverseOfPotentialMaterialization(graph, existingState, definition.inverseKey, op.record, isRemote);
1428
+ } else if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_RELATIONSHIP_REMOTE_UPDATE_CLEARING_LOCAL_STATE)) {
1429
+ // if localState does not match existingState then we know
1430
+ // we have a local mutation that has not been persisted yet
1431
+ if (localState !== op.value && relationship.definition.resetOnRemoteUpdate !== false) {
1432
+ relationship.localState = existingState;
1433
+ deprecate(`WarpDrive is changing the default semantics of updates to the remote state of relationships.\n\nThe following local state was cleared from the <${relationship.identifier.type}>.${relationship.definition.key} belongsTo relationship but will not be once this deprecation is resolved:\n\n\t${localState ? 'Added: ' + localState.lid + '\n\t' : ''}${existingState ? 'Removed: ' + existingState.lid : ''}`, false, {
1434
+ id: 'ember-data:deprecate-relationship-remote-update-clearing-local-state',
1435
+ for: 'ember-data',
1436
+ since: {
1437
+ enabled: '5.3',
1438
+ available: '4.13'
1439
+ },
1440
+ until: '6.0',
1441
+ url: 'https://deprecations.emberjs.com/v5.x#ember-data-deprecate-relationship-remote-update-clearing-local-state'
1442
+ });
1443
+ notifyChange(graph, relationship);
1444
+ }
1445
+ }
1446
+ }
1447
+ return;
1448
+ }
1449
+
1450
+ // remove this value from the inverse if required
1451
+ if (existingState) {
1452
+ removeFromInverse(graph, existingState, definition.inverseKey, op.record, isRemote);
1453
+ }
1454
+
1455
+ // update value to the new value
1456
+ relationship[prop] = op.value;
1457
+ state.hasReceivedData = true;
1458
+ state.isEmpty = op.value === null;
1459
+ state.isStale = false;
1460
+ state.hasFailedLoadAttempt = false;
1461
+ if (op.value) {
1462
+ if (definition.type !== op.value.type) {
1463
+ // assert(
1464
+ // `The '<${definition.inverseType}>.${op.field}' relationship expects only '${definition.type}' records since it is not polymorphic. Received a Record of type '${op.value.type}'`,
1465
+ // definition.isPolymorphic
1466
+ // );
1467
+
1468
+ // TODO this should now handle the deprecation warning if isPolymorphic is not set
1469
+ // but the record does turn out to be polymorphic
1470
+ // this should still assert if the user is relying on legacy inheritance/mixins to
1471
+ // provide polymorphic behavior and has not yet added the polymorphic flags
1472
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
1473
+ assertPolymorphicType(relationship.identifier, definition, op.value, graph.store);
1474
+ }
1475
+ graph.registerPolymorphicType(definition.type, op.value.type);
1476
+ }
1477
+ addToInverse(graph, op.value, definition.inverseKey, op.record, isRemote);
1478
+ }
1479
+ if (isRemote) {
1480
+ const {
1481
+ localState,
1482
+ remoteState
1483
+ } = relationship;
1484
+ if (localState && checkIfNew(graph._realStore, localState) && !remoteState) {
1485
+ return;
1486
+ }
1487
+ // when localState does not match the new remoteState and
1488
+ // localState === existingState then we had no local mutation
1489
+ // and we can safely sync the new remoteState to local
1490
+ if (localState !== remoteState && localState === existingState) {
1491
+ relationship.localState = remoteState;
1492
+ notifyChange(graph, relationship);
1493
+ // But when localState does not match the new remoteState and
1494
+ // and localState !== existingState then we know we have a local mutation
1495
+ // that has not been persisted yet.
1496
+ } else if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_RELATIONSHIP_REMOTE_UPDATE_CLEARING_LOCAL_STATE)) {
1497
+ if (localState !== remoteState && localState !== existingState && relationship.definition.resetOnRemoteUpdate !== false) {
1498
+ relationship.localState = remoteState;
1499
+ deprecate(`WarpDrive is changing the default semantics of updates to the remote state of relationships.\n\nThe following local state was cleared from the <${relationship.identifier.type}>.${relationship.definition.key} belongsTo relationship but will not be once this deprecation is resolved:\n\n\t${localState ? 'Added: ' + localState.lid + '\n\t' : ''}${existingState ? 'Removed: ' + existingState.lid : ''}`, false, {
1500
+ id: 'ember-data:deprecate-relationship-remote-update-clearing-local-state',
1501
+ for: 'ember-data',
1502
+ since: {
1503
+ enabled: '5.3',
1504
+ available: '4.13'
1505
+ },
1506
+ until: '6.0',
1507
+ url: 'https://deprecations.emberjs.com/v5.x#ember-data-deprecate-relationship-remote-update-clearing-local-state'
1508
+ });
1509
+ notifyChange(graph, relationship);
1510
+ }
1511
+ }
1512
+ } else {
1513
+ notifyChange(graph, relationship);
1514
+ }
1515
+ }
1516
+ function _deprecatedCompare(priorLocalState, newState, newMembers, prevState, prevSet, onAdd, onDel, remoteClearsLocal) {
1517
+ const newLength = newState.length;
1518
+ const prevLength = prevState.length;
1519
+ const iterationLength = Math.max(newLength, prevLength);
1520
+ let changed = newMembers.size !== prevSet.size;
1521
+ let remoteOrderChanged = false;
1522
+ const added = new Set();
1523
+ const removed = new Set();
1524
+ const duplicates = new Map();
1525
+ const finalSet = new Set();
1526
+ const finalState = [];
1527
+ const priorLocalLength = priorLocalState?.length ?? 0;
1528
+ for (let i = 0, j = 0; i < iterationLength; i++) {
1529
+ let adv = false;
1530
+ let member;
1531
+
1532
+ // accumulate anything added
1533
+ if (i < newLength) {
1534
+ member = newState[i];
1535
+ if (!finalSet.has(member)) {
1536
+ finalState[j] = member;
1537
+ finalSet.add(member);
1538
+ adv = true;
1539
+ if (!prevSet.has(member)) {
1540
+ // Avoid unnecessarily notifying a change that already exists locally
1541
+ if (i < priorLocalLength) {
1542
+ const priorLocalMember = priorLocalState[i];
1543
+ if (priorLocalMember !== member) {
1544
+ changed = true;
1545
+ }
1546
+ }
1547
+ added.add(member);
1548
+ onAdd(member);
1549
+ }
1550
+ } else {
1551
+ let list = duplicates.get(member);
1552
+ if (list === undefined) {
1553
+ list = [];
1554
+ duplicates.set(member, list);
1555
+ }
1556
+ list.push(i);
1557
+ }
1558
+ }
1559
+
1560
+ // accumulate anything removed
1561
+ if (i < prevLength) {
1562
+ const prevMember = prevState[i];
1563
+
1564
+ // detect reordering, adjusting index for duplicates
1565
+ // j is always less than i and so if i < prevLength, j < prevLength
1566
+ if (member !== prevState[j]) {
1567
+ // the new remote order does not match the current remote order
1568
+ // indicating a change in membership or reordering
1569
+ remoteOrderChanged = true;
1570
+ // however: if the new remote order matches the current local order
1571
+ // we can disregard the change notification generation so long as
1572
+ // we are not configured to reset on remote update (which is deprecated)
1573
+ if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_RELATIONSHIP_REMOTE_UPDATE_CLEARING_LOCAL_STATE)) {
1574
+ if (!remoteClearsLocal && i < priorLocalLength) {
1575
+ const priorLocalMember = priorLocalState[j];
1576
+ if (priorLocalMember !== member) {
1577
+ changed = true;
1578
+ }
1579
+ } else {
1580
+ changed = true;
1581
+ }
1582
+ } else {
1583
+ if (i < priorLocalLength) {
1584
+ const priorLocalMember = priorLocalState[j];
1585
+ if (priorLocalMember !== member) {
1586
+ changed = true;
1587
+ }
1588
+ } else {
1589
+ changed = true;
1590
+ }
1591
+ }
1592
+
1593
+ // if remote order hasn't changed but local order differs
1594
+ // and we are configured to reset on remote update (which is deprecated)
1595
+ // then we still need to mark the relationship as changed
1596
+ } else if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_RELATIONSHIP_REMOTE_UPDATE_CLEARING_LOCAL_STATE)) {
1597
+ if (remoteClearsLocal) {
1598
+ if (!changed && j < priorLocalLength) {
1599
+ const priorLocalMember = priorLocalState[j];
1600
+ if (priorLocalMember !== member) {
1601
+ changed = true;
1602
+ }
1603
+ }
1604
+ }
1605
+ }
1606
+ if (!newMembers.has(prevMember)) {
1607
+ changed = true;
1608
+ removed.add(prevMember);
1609
+ onDel(prevMember);
1610
+ }
1611
+ } else if (adv && j < prevLength && member !== prevState[j]) {
1612
+ changed = true;
1613
+ }
1614
+ if (adv) {
1615
+ j++;
1616
+ }
1617
+ }
1618
+ const diff = {
1619
+ add: added,
1620
+ del: removed,
1621
+ finalState,
1622
+ finalSet,
1623
+ changed,
1624
+ remoteOrderChanged
1625
+ };
1626
+ return {
1627
+ diff,
1628
+ duplicates
1629
+ };
1630
+ }
1631
+ function _compare(priorLocalState, finalState, finalSet, prevState, prevSet, onAdd, onDel, remoteClearsLocal) {
1632
+ const finalLength = finalState.length;
1633
+ const prevLength = prevState.length;
1634
+ const iterationLength = Math.max(finalLength, prevLength);
1635
+ const equalLength = priorLocalState ? finalLength === priorLocalState.length : finalLength === prevLength;
1636
+ let remoteOrderChanged = finalSet.size !== prevSet.size;
1637
+ let changed = priorLocalState ? finalSet.size !== priorLocalState.length : remoteOrderChanged;
1638
+ const added = new Set();
1639
+ const removed = new Set();
1640
+ const priorLocalLength = priorLocalState?.length ?? 0;
1641
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.DEBUG_RELATIONSHIP_NOTIFICATIONS)) {
1642
+ if (getGlobalConfig().WarpDrive.debug.DEBUG_RELATIONSHIP_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.DEBUG_RELATIONSHIP_NOTIFICATIONS) {
1643
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
1644
+ changed &&
1645
+ // eslint-disable-next-line no-console
1646
+ console.log(`changed because ${priorLocalState ? 'finalSet.size !== priorLocalState.length' : 'finalSet.size !== prevSet.size'}`);
1647
+ }
1648
+ }
1649
+ for (let i = 0; i < iterationLength; i++) {
1650
+ let member;
1651
+
1652
+ // accumulate anything added
1653
+ if (i < finalLength) {
1654
+ member = finalState[i];
1655
+ if (!prevSet.has(member)) {
1656
+ // Avoid unnecessarily notifying a change that already exists locally
1657
+ if (i < priorLocalLength) {
1658
+ const priorLocalMember = priorLocalState[i];
1659
+ if (priorLocalMember !== member) {
1660
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.DEBUG_RELATIONSHIP_NOTIFICATIONS)) {
1661
+ if (getGlobalConfig().WarpDrive.debug.DEBUG_RELATIONSHIP_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.DEBUG_RELATIONSHIP_NOTIFICATIONS) {
1662
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions, no-console
1663
+ !changed && console.log(`changed because priorLocalMember !== member && !prevSet.has(member)`);
1664
+ }
1665
+ }
1666
+ changed = true;
1667
+ }
1668
+ }
1669
+ added.add(member);
1670
+ onAdd(member);
1671
+ }
1672
+ }
1673
+
1674
+ // accumulate anything removed
1675
+ if (i < prevLength) {
1676
+ const prevMember = prevState[i];
1677
+
1678
+ // detect reordering
1679
+ if (equalLength && member !== prevMember) {
1680
+ // the new remote order does not match the current remote order
1681
+ // indicating a change in membership or reordering
1682
+ remoteOrderChanged = true;
1683
+ // however: if the new remote order matches the current local order
1684
+ // we can disregard the change notification generation so long as
1685
+ // we are not configured to reset on remote update (which is deprecated)
1686
+
1687
+ if (i < priorLocalLength) {
1688
+ const priorLocalMember = priorLocalState[i];
1689
+ if (priorLocalMember !== member) {
1690
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.DEBUG_RELATIONSHIP_NOTIFICATIONS)) {
1691
+ if (getGlobalConfig().WarpDrive.debug.DEBUG_RELATIONSHIP_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.DEBUG_RELATIONSHIP_NOTIFICATIONS) {
1692
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions, no-console
1693
+ !changed && console.log(`changed because priorLocalMember !== member && member !== prevMember`);
1694
+ }
1695
+ }
1696
+ changed = true;
1697
+ }
1698
+ } else if (i < finalLength) {
1699
+ // if we have exceeded the length of priorLocalState and we are within the range
1700
+ // of the finalState then we must have changed
1701
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.DEBUG_RELATIONSHIP_NOTIFICATIONS)) {
1702
+ if (getGlobalConfig().WarpDrive.debug.DEBUG_RELATIONSHIP_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.DEBUG_RELATIONSHIP_NOTIFICATIONS) {
1703
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions, no-console
1704
+ !changed && console.log(`changed because priorMember !== member && index >= priorLocalLength`);
1705
+ }
1706
+ }
1707
+ changed = true;
1708
+ }
1709
+
1710
+ // if remote order hasn't changed but local order differs
1711
+ // and we are configured to reset on remote update (which is deprecated)
1712
+ // then we still need to mark the relationship as changed
1713
+ } else if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_RELATIONSHIP_REMOTE_UPDATE_CLEARING_LOCAL_STATE)) {
1714
+ if (remoteClearsLocal) {
1715
+ if (equalLength && !changed && i < priorLocalLength) {
1716
+ const priorLocalMember = priorLocalState[i];
1717
+ if (priorLocalMember !== prevMember) {
1718
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.DEBUG_RELATIONSHIP_NOTIFICATIONS)) {
1719
+ if (getGlobalConfig().WarpDrive.debug.DEBUG_RELATIONSHIP_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.DEBUG_RELATIONSHIP_NOTIFICATIONS) {
1720
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions, no-console
1721
+ !changed && console.log(`changed because priorLocalMember !== prevMember && remoteClearsLocal`);
1722
+ }
1723
+ }
1724
+ changed = true;
1725
+ }
1726
+ }
1727
+ }
1728
+ }
1729
+ if (!finalSet.has(prevMember)) {
1730
+ // if we are within finalLength, we can only be "changed" if we've already exceeded
1731
+ // the index range of priorLocalState, as otherwise the previous member may still
1732
+ // be removed.
1733
+ //
1734
+ // prior local: [1, 2, 3, 4]
1735
+ // final state: [1, 2, 3]
1736
+ // prev remote state: [1, 2, 5, 3, 4]
1737
+ // i === 2
1738
+ // prevMember === 5
1739
+ // !finalSet.has(prevMember) === true
1740
+ //
1741
+ // because we will become changed at i===3,
1742
+ // we do not need to worry about becoming changed at i===2
1743
+ // as the arrays until now are still the same
1744
+ //
1745
+ // prior local: [1, 2, 3]
1746
+ // final state: [1, 2, 3, 4]
1747
+ // prev remote state: [1, 2, 5, 3, 4]
1748
+ // i === 2
1749
+ // prevMember === 5
1750
+ // !finalSet.has(prevMember) === true
1751
+ //
1752
+ // because we will become changed at i===3
1753
+ // we do not need to worry about becoming changed at i===2
1754
+ //
1755
+ // prior local: [1, 2, 3]
1756
+ // final state: [1, 2, 3]
1757
+ // prev remote state: [1, 2, 5, 3, 4]
1758
+ // i === 2
1759
+ // prevMember === 5
1760
+ // !finalSet.has(prevMember) === true
1761
+ //
1762
+ // because we have same length and same membership order
1763
+ // we do not need to worry about becoming changed at i===2
1764
+ //
1765
+ // if you do not have a priorLocalState you can't be changed
1766
+ // ergo, we never need to set changed in this branch.
1767
+ // this log can still be useful for debugging.
1768
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.DEBUG_RELATIONSHIP_NOTIFICATIONS)) {
1769
+ if (getGlobalConfig().WarpDrive.debug.DEBUG_RELATIONSHIP_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.DEBUG_RELATIONSHIP_NOTIFICATIONS) {
1770
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
1771
+ !changed &&
1772
+ // eslint-disable-next-line no-console
1773
+ console.log(`changed because i >= priorLocalLength && i < finalLength && !finalSet.has(prevMember)`);
1774
+ }
1775
+ }
1776
+ //
1777
+ // we do still set remoteOrderChanged as it has
1778
+ remoteOrderChanged = true;
1779
+ removed.add(prevMember);
1780
+ onDel(prevMember);
1781
+ }
1782
+ }
1783
+ }
1784
+ return {
1785
+ add: added,
1786
+ del: removed,
1787
+ finalState,
1788
+ finalSet,
1789
+ changed,
1790
+ remoteOrderChanged
1791
+ };
1792
+ }
1793
+ function diffCollection(finalState, relationship, onAdd, onDel) {
1794
+ const finalSet = new Set(finalState);
1795
+ const {
1796
+ localState: priorLocalState,
1797
+ remoteState,
1798
+ remoteMembers
1799
+ } = relationship;
1800
+ if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_NON_UNIQUE_PAYLOADS)) {
1801
+ if (finalState.length !== finalSet.size) {
1802
+ const {
1803
+ diff,
1804
+ duplicates
1805
+ } = _deprecatedCompare(priorLocalState, finalState, finalSet, remoteState, remoteMembers, onAdd, onDel, relationship.definition.resetOnRemoteUpdate);
1806
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
1807
+ deprecate(`Expected all entries in the relationship ${relationship.definition.type}:${relationship.definition.key} to be unique, see log for a list of duplicate entry indeces`, false, {
1808
+ id: 'ember-data:deprecate-non-unique-relationship-entries',
1809
+ for: 'ember-data',
1810
+ until: '6.0',
1811
+ since: {
1812
+ available: '4.13',
1813
+ enabled: '5.3'
1814
+ }
1815
+ });
1816
+ // eslint-disable-next-line no-console
1817
+ console.log(duplicates);
1818
+ }
1819
+ return diff;
1820
+ }
1821
+ } else {
1822
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1823
+ if (!test) {
1824
+ throw new Error(`Expected all entries in the relationship to be unique, found duplicates`);
1825
+ }
1826
+ })(finalState.length === finalSet.size) : {};
1827
+ }
1828
+ return _compare(priorLocalState, finalState, finalSet, remoteState, remoteMembers, onAdd, onDel, relationship.definition.resetOnRemoteUpdate);
1829
+ }
1830
+ function computeLocalState(storage) {
1831
+ if (!storage.isDirty) {
1832
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1833
+ if (!test) {
1834
+ throw new Error(`Expected localState to be present`);
1835
+ }
1836
+ })(Array.isArray(storage.localState)) : {};
1837
+ return storage.localState;
1838
+ }
1839
+ const state = storage.remoteState.slice();
1840
+ storage.removals?.forEach(v => {
1841
+ const index = state.indexOf(v);
1842
+ state.splice(index, 1);
1843
+ });
1844
+ storage.additions?.forEach(v => {
1845
+ state.push(v);
1846
+ });
1847
+ storage.localState = state;
1848
+ storage.isDirty = false;
1849
+ return state;
1850
+ }
1851
+
1852
+ /**
1853
+ * A function which attempts to add a value to the local state of a collection
1854
+ * relationship, and returns true if the value was added, or false if it was
1855
+ * already present.
1856
+ *
1857
+ * It will not generate a notification, will not update the relationships to dirty,
1858
+ * and will not update the inverse relationships, making it suitable for use as
1859
+ * an internal util to perform the just the addition to a specific side of a
1860
+ * relationship.
1861
+ *
1862
+ * @internal
1863
+ */
1864
+ function _add(graph, record, relationship, value, index, isRemote) {
1865
+ return !isRemote ? _addLocal(graph, record, relationship, value, index) : _addRemote(graph, record, relationship, value, index);
1866
+ }
1867
+ function _addRemote(graph, record, relationship, value, index) {
1868
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1869
+ if (!test) {
1870
+ throw new Error(`expected an identifier to add to the collection relationship`);
1871
+ }
1872
+ })(value) : {};
1873
+ const {
1874
+ remoteMembers,
1875
+ additions,
1876
+ removals,
1877
+ remoteState
1878
+ } = relationship;
1879
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1880
+ if (!test) {
1881
+ throw new Error(`Cannot add a resource that is already present`);
1882
+ }
1883
+ })(!remoteMembers.has(value)) : {};
1884
+ if (remoteMembers.has(value)) {
1885
+ return false;
1886
+ }
1887
+
1888
+ // add to the remote state
1889
+ remoteMembers.add(value);
1890
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1891
+ if (!test) {
1892
+ throw new Error(`Cannot insert at an index that is not in bounds`);
1893
+ }
1894
+ })(index === null || index >= 0 && index < remoteState.length) : {};
1895
+ const hasValidIndex = index !== null && index >= 0 && index < remoteState.length;
1896
+ if (hasValidIndex) {
1897
+ remoteState.splice(index, 0, value);
1898
+ } else {
1899
+ remoteState.push(value);
1900
+ }
1901
+
1902
+ // remove from additions if present
1903
+ if (additions?.has(value)) {
1904
+ additions.delete(value);
1905
+
1906
+ // nothing more to do this was our state already
1907
+ return false;
1908
+ }
1909
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1910
+ if (!test) {
1911
+ throw new Error(`Remote state indicated addition of a resource that was present only as a local mutation`);
1912
+ }
1913
+ })(!removals?.has(value)) : {};
1914
+
1915
+ // if the relationship already needs to recalc, we don't bother
1916
+ // attempting to patch the localState
1917
+ if (relationship.isDirty) {
1918
+ return true;
1919
+ }
1920
+
1921
+ // if we have existing localState
1922
+ // we attempt to patch it without blowing it away
1923
+ // as this is more efficient than recomputing
1924
+ // it allows us to preserve local ordering
1925
+ // to a small extent. Local ordering should not
1926
+ // be relied upon as any remote change could blow it away
1927
+ if (relationship.localState) {
1928
+ if (!hasValidIndex) {
1929
+ relationship.localState.push(value);
1930
+ } else if (index === 0) {
1931
+ relationship.localState.unshift(value);
1932
+ } else if (!removals?.size) {
1933
+ relationship.localState.splice(index, 0, value);
1934
+ } else {
1935
+ relationship.isDirty = true;
1936
+ }
1937
+ }
1938
+ return true;
1939
+ }
1940
+ function _addLocal(graph, record, relationship, value, index) {
1941
+ const {
1942
+ remoteMembers,
1943
+ removals
1944
+ } = relationship;
1945
+ let additions = relationship.additions;
1946
+ const hasPresence = remoteMembers.has(value) || additions?.has(value);
1947
+ if (hasPresence && !removals?.has(value)) {
1948
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1949
+ if (!test) {
1950
+ throw new Error(`Attempted to add the resource '${value.lid}' to the collection <${relationship.identifier.type}>.${relationship.definition.key} it was already in`);
1951
+ }
1952
+ })(hasPresence && !removals?.has(value)) : {};
1953
+ return false;
1954
+ }
1955
+ if (removals?.has(value)) {
1956
+ removals.delete(value);
1957
+ } else {
1958
+ if (!additions) {
1959
+ additions = relationship.additions = new Set();
1960
+ }
1961
+ relationship.state.hasReceivedData = true;
1962
+ additions.add(value);
1963
+ const {
1964
+ type
1965
+ } = relationship.definition;
1966
+ if (type !== value.type) {
1967
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
1968
+ assertPolymorphicType(record, relationship.definition, value, graph.store);
1969
+ }
1970
+ graph.registerPolymorphicType(value.type, type);
1971
+ }
1972
+ }
1973
+
1974
+ // if we have existing localState
1975
+ // and we have an index
1976
+ // apply the change, as this is more efficient
1977
+ // than recomputing localState and
1978
+ // it allows us to preserve local ordering
1979
+ // to a small extend. Local ordering should not
1980
+ // be relied upon as any remote change will blow it away
1981
+ if (relationship.localState) {
1982
+ if (index !== null) {
1983
+ relationship.localState.splice(index, 0, value);
1984
+ } else {
1985
+ relationship.localState.push(value);
1986
+ }
1987
+ }
1988
+ return true;
1989
+ }
1990
+ function _remove(graph, record, relationship, value, index, isRemote) {
1991
+ return !isRemote ? _removeLocal(relationship, value) : _removeRemote(relationship, value);
1992
+ }
1993
+ function _removeLocal(relationship, value) {
1994
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1995
+ if (!test) {
1996
+ throw new Error(`expected an identifier to remove from the collection relationship`);
1997
+ }
1998
+ })(value) : {};
1999
+ const {
2000
+ remoteMembers,
2001
+ additions
2002
+ } = relationship;
2003
+ let removals = relationship.removals;
2004
+ const hasPresence = remoteMembers.has(value) || additions?.has(value);
2005
+ if (!hasPresence || removals?.has(value)) {
2006
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2007
+ if (!test) {
2008
+ throw new Error(`Attempted to remove the resource '${value.lid}' from the collection <${relationship.identifier.type}>.${relationship.definition.key} but it was not present`);
2009
+ }
2010
+ })(!hasPresence || removals?.has(value)) : {};
2011
+ return false;
2012
+ }
2013
+ if (additions?.has(value)) {
2014
+ additions.delete(value);
2015
+ } else {
2016
+ if (!removals) {
2017
+ removals = relationship.removals = new Set();
2018
+ }
2019
+ removals.add(value);
2020
+ }
2021
+
2022
+ // if we have existing localState
2023
+ // apply the change, as this is more efficient
2024
+ // than recomputing localState and
2025
+ // it allows us to preserve local ordering
2026
+ // to a small extend. Local ordering should not
2027
+ // be relied upon as any remote change will blow it away
2028
+ if (relationship.localState) {
2029
+ const index = relationship.localState.indexOf(value);
2030
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2031
+ if (!test) {
2032
+ throw new Error(`Cannot remove a resource that is not present`);
2033
+ }
2034
+ })(index !== -1) : {};
2035
+ relationship.localState.splice(index, 1);
2036
+ }
2037
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2038
+ if (!test) {
2039
+ throw new Error(`Expected relationship to be dirty when performing a local mutation`);
2040
+ }
2041
+ })(relationship.localState || relationship.isDirty) : {};
2042
+ return true;
2043
+ }
2044
+ function _removeRemote(relationship, value) {
2045
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2046
+ if (!test) {
2047
+ throw new Error(`expected an identifier to remove from the collection relationship`);
2048
+ }
2049
+ })(value) : {};
2050
+ const {
2051
+ remoteMembers,
2052
+ additions,
2053
+ removals,
2054
+ remoteState
2055
+ } = relationship;
2056
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2057
+ if (!test) {
2058
+ throw new Error(`Cannot remove a resource that is not present`);
2059
+ }
2060
+ })(remoteMembers.has(value)) : {};
2061
+ if (!remoteMembers.has(value)) {
2062
+ return false;
2063
+ }
2064
+
2065
+ // remove from remote state
2066
+ remoteMembers.delete(value);
2067
+ let index = remoteState.indexOf(value);
2068
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2069
+ if (!test) {
2070
+ throw new Error(`Cannot remove a resource that is not present`);
2071
+ }
2072
+ })(index !== -1) : {};
2073
+ remoteState.splice(index, 1);
2074
+
2075
+ // remove from removals if present
2076
+ if (removals?.has(value)) {
2077
+ removals.delete(value);
2078
+
2079
+ // nothing more to do this was our state already
2080
+ return false;
2081
+ }
2082
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2083
+ if (!test) {
2084
+ throw new Error(`Remote state indicated removal of a resource that was present only as a local mutation`);
2085
+ }
2086
+ })(!additions?.has(value)) : {};
2087
+
2088
+ // if we have existing localState
2089
+ // and we have an index
2090
+ // apply the change, as this is more efficient
2091
+ // than recomputing localState and
2092
+ // it allows us to preserve local ordering
2093
+ // to a small extend. Local ordering should not
2094
+ // be relied upon as any remote change will blow it away
2095
+ if (relationship.localState) {
2096
+ index = relationship.localState.indexOf(value);
2097
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2098
+ if (!test) {
2099
+ throw new Error(`Cannot remove a resource that is not present`);
2100
+ }
2101
+ })(index !== -1) : {};
2102
+ relationship.localState.splice(index, 1);
2103
+ }
2104
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2105
+ if (!test) {
2106
+ throw new Error(`Expected relationship to be dirty when performing a local mutation`);
2107
+ }
2108
+ })(relationship.localState || relationship.isDirty) : {};
2109
+ return true;
2110
+ }
2111
+ function rollbackRelationship(graph, key, field, relationship) {
2112
+ if (isBelongsTo(relationship)) {
2113
+ replaceRelatedRecord(graph, {
2114
+ op: 'replaceRelatedRecord',
2115
+ record: key,
2116
+ field,
2117
+ value: relationship.remoteState
2118
+ }, false);
2119
+ } else {
2120
+ replaceRelatedRecords(graph, {
2121
+ op: 'replaceRelatedRecords',
2122
+ record: key,
2123
+ field,
2124
+ value: relationship.remoteState.slice()
2125
+ }, false);
2126
+
2127
+ // when the change was a "reorder" only we wont have generated
2128
+ // a notification yet.
2129
+ // if we give rollback a unique operation we can use the ability of
2130
+ // diff to report a separate `remoteOrderChanged` flag to trigger this
2131
+ // if needed to avoid the duplicate.
2132
+ notifyChange(graph, relationship);
2133
+ }
2134
+ }
2135
+ function createState() {
2136
+ return {
2137
+ hasReceivedData: false,
2138
+ isEmpty: true,
2139
+ isStale: false,
2140
+ hasFailedLoadAttempt: false,
2141
+ shouldForceReload: false,
2142
+ hasDematerializedInverse: false
2143
+ };
2144
+ }
2145
+ function createCollectionEdge(definition, identifier) {
2146
+ return {
2147
+ definition,
2148
+ identifier,
2149
+ state: createState(),
2150
+ remoteMembers: new Set(),
2151
+ remoteState: [],
2152
+ additions: null,
2153
+ removals: null,
2154
+ meta: null,
2155
+ links: null,
2156
+ localState: null,
2157
+ isDirty: false,
2158
+ transactionRef: 0,
2159
+ accessed: false,
2160
+ _diff: undefined
2161
+ };
2162
+ }
2163
+ function legacyGetCollectionRelationshipData(source, getRemoteState) {
2164
+ source.accessed = true;
2165
+ const payload = {};
2166
+ if (source.state.hasReceivedData) {
2167
+ payload.data = getRemoteState ? source.remoteState.slice() : computeLocalState(source);
2168
+ }
2169
+ if (source.links) {
2170
+ payload.links = source.links;
2171
+ }
2172
+ if (source.meta) {
2173
+ payload.meta = source.meta;
2174
+ }
2175
+ return payload;
2176
+ }
2177
+
2178
+ /**
2179
+ Implicit relationships are relationships which have not been declared but the inverse side exists on
2180
+ another record somewhere
2181
+
2182
+ For example consider the following two models
2183
+
2184
+ ::: code-group
2185
+
2186
+ ```js [./models/comment.js]
2187
+ import { Model, attr } from '@warp-drive/legacy/model';
2188
+
2189
+ export default class Comment extends Model {
2190
+ @attr text;
2191
+ }
2192
+ ```
2193
+
2194
+ ```js [./models/post.js]
2195
+ import { Model, attr, hasMany } from '@warp-drive/legacy/model';
2196
+
2197
+ export default class Post extends Model {
2198
+ @attr title;
2199
+ @hasMany('comment', { async: true, inverse: null }) comments;
2200
+ }
2201
+ ```
2202
+
2203
+ :::
2204
+
2205
+ Then we would have a implicit 'post' relationship for the comment record in order
2206
+ to be do things like remove the comment from the post if the comment were to be deleted.
2207
+ */
2208
+
2209
+ function createImplicitEdge(definition, identifier) {
2210
+ return {
2211
+ definition,
2212
+ identifier,
2213
+ localMembers: new Set(),
2214
+ remoteMembers: new Set()
2215
+ };
2216
+ }
2217
+
2218
+ /**
2219
+ * Stores the data for one side of a "single" resource relationship.
2220
+ *
2221
+ * @private
2222
+ */
2223
+
2224
+ function createResourceEdge(definition, identifier) {
2225
+ return {
2226
+ definition,
2227
+ identifier,
2228
+ state: createState(),
2229
+ transactionRef: 0,
2230
+ localState: null,
2231
+ remoteState: null,
2232
+ meta: null,
2233
+ links: null,
2234
+ accessed: false
2235
+ };
2236
+ }
2237
+ function legacyGetResourceRelationshipData(source, getRemoteState) {
2238
+ source.accessed = true;
2239
+ let data;
2240
+ const payload = {};
2241
+ if (getRemoteState && source.remoteState) {
2242
+ data = source.remoteState;
2243
+ } else if (!getRemoteState && source.localState) {
2244
+ data = source.localState;
2245
+ }
2246
+ if ((getRemoteState && source.remoteState === null || source.localState === null) && source.state.hasReceivedData) {
2247
+ data = null;
2248
+ }
2249
+ if (source.links) {
2250
+ payload.links = source.links;
2251
+ }
2252
+ if (data !== undefined) {
2253
+ payload.data = data;
2254
+ }
2255
+ if (source.meta) {
2256
+ payload.meta = source.meta;
2257
+ }
2258
+ return payload;
2259
+ }
2260
+ function addToRelatedRecords(graph, op, isRemote) {
2261
+ const {
2262
+ record,
2263
+ value,
2264
+ index
2265
+ } = op;
2266
+ const relationship = graph.get(record, op.field);
2267
+ const _isBelongsTo = isBelongsTo(relationship);
2268
+ if (isRemote && _isBelongsTo) {
2269
+ if (value !== relationship.remoteState) {
2270
+ const newOp = {
2271
+ op: 'replaceRelatedRecord',
2272
+ record,
2273
+ field: op.field,
2274
+ value: value
2275
+ };
2276
+ return replaceRelatedRecord(graph, newOp, isRemote);
2277
+ }
2278
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2279
+ if (!test) {
2280
+ throw new Error(`Expected '${value?.lid}' (the value to add) to NOT be the same as the remote state '${relationship.remoteState?.lid ?? '<null>'}'`);
2281
+ }
2282
+ })(value === relationship.remoteState) : {};
2283
+ return;
2284
+ }
2285
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2286
+ if (!test) {
2287
+ throw new Error(`You can only '${op.op}' on a hasMany relationship. ${record.type}.${op.field} is a ${relationship.definition.kind}`);
2288
+ }
2289
+ })(isHasMany(relationship)) : {};
2290
+
2291
+ // if we are not dirty but have a null localState then we
2292
+ // are mutating a relationship that has never been fetched
2293
+ // so we initialize localState to an empty array
2294
+ if (!relationship.isDirty && !relationship.localState) {
2295
+ relationship.localState = [];
2296
+ }
2297
+ if (Array.isArray(value)) {
2298
+ for (let i = 0; i < value.length; i++) {
2299
+ addRelatedRecord(graph, relationship, record, value[i], index !== undefined ? index + i : null, isRemote);
2300
+ }
2301
+ } else {
2302
+ addRelatedRecord(graph, relationship, record, value, index ?? null, isRemote);
2303
+ }
2304
+ notifyChange(graph, relationship);
2305
+ }
2306
+ function addRelatedRecord(graph, relationship, record, value, index, isRemote) {
2307
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2308
+ if (!test) {
2309
+ throw new Error(`expected an identifier to add to the collection relationship`);
2310
+ }
2311
+ })(value) : {};
2312
+ if (_add(graph, record, relationship, value, index, isRemote)) {
2313
+ addToInverse(graph, value, relationship.definition.inverseKey, record, isRemote);
2314
+ }
2315
+ }
2316
+ function mergeIdentifier(graph, op, relationships) {
2317
+ Object.keys(relationships).forEach(key => {
2318
+ const rel = relationships[key];
2319
+ if (!rel) {
2320
+ return;
2321
+ }
2322
+ mergeIdentifierForRelationship(graph, op, rel);
2323
+ });
2324
+ }
2325
+ function mergeIdentifierForRelationship(graph, op, rel) {
2326
+ rel.identifier = op.value;
2327
+ forAllRelatedIdentifiers(rel, identifier => {
2328
+ const inverse = graph.get(identifier, rel.definition.inverseKey);
2329
+ mergeInRelationship(graph, inverse, op);
2330
+ });
2331
+ }
2332
+ function mergeInRelationship(graph, rel, op) {
2333
+ if (isBelongsTo(rel)) {
2334
+ mergeBelongsTo(graph, rel, op);
2335
+ } else if (isHasMany(rel)) {
2336
+ mergeHasMany(graph, rel, op);
2337
+ } else {
2338
+ mergeImplicit(graph, rel, op);
2339
+ }
2340
+ }
2341
+ function mergeBelongsTo(graph, rel, op) {
2342
+ if (rel.remoteState === op.record) {
2343
+ rel.remoteState = op.value;
2344
+ }
2345
+ if (rel.localState === op.record) {
2346
+ rel.localState = op.value;
2347
+ notifyChange(graph, rel);
2348
+ }
2349
+ }
2350
+ function mergeHasMany(graph, rel, op) {
2351
+ if (rel.remoteMembers.has(op.record)) {
2352
+ rel.remoteMembers.delete(op.record);
2353
+ rel.remoteMembers.add(op.value);
2354
+ const index = rel.remoteState.indexOf(op.record);
2355
+ rel.remoteState.splice(index, 1, op.value);
2356
+ rel.isDirty = true;
2357
+ }
2358
+ if (rel.additions?.has(op.record)) {
2359
+ rel.additions.delete(op.record);
2360
+ rel.additions.add(op.value);
2361
+ rel.isDirty = true;
2362
+ }
2363
+ if (rel.removals?.has(op.record)) {
2364
+ rel.removals.delete(op.record);
2365
+ rel.removals.add(op.value);
2366
+ rel.isDirty = true;
2367
+ }
2368
+ if (rel.isDirty) {
2369
+ notifyChange(graph, rel);
2370
+ }
2371
+ }
2372
+ function mergeImplicit(graph, rel, op) {
2373
+ if (rel.remoteMembers.has(op.record)) {
2374
+ rel.remoteMembers.delete(op.record);
2375
+ rel.remoteMembers.add(op.value);
2376
+ }
2377
+ if (rel.localMembers.has(op.record)) {
2378
+ rel.localMembers.delete(op.record);
2379
+ rel.localMembers.add(op.value);
2380
+ }
2381
+ }
2382
+ function removeFromRelatedRecords(graph, op, isRemote) {
2383
+ const {
2384
+ record,
2385
+ value
2386
+ } = op;
2387
+ const relationship = graph.get(record, op.field);
2388
+ const _isBelongsTo = isBelongsTo(relationship);
2389
+ if (isRemote && _isBelongsTo) {
2390
+ if (value === relationship.remoteState) {
2391
+ const newOp = {
2392
+ op: 'replaceRelatedRecord',
2393
+ record,
2394
+ field: op.field,
2395
+ value: null
2396
+ };
2397
+ return replaceRelatedRecord(graph, newOp, isRemote);
2398
+ }
2399
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2400
+ if (!test) {
2401
+ throw new Error(`Expected '${value?.lid}' (the value to remove) to be the same as the remote state '${relationship.remoteState?.lid ?? '<null>'}'`);
2402
+ }
2403
+ })(value === relationship.remoteState) : {};
2404
+ return;
2405
+ }
2406
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2407
+ if (!test) {
2408
+ throw new Error(`You can only '${op.op}' on a hasMany relationship. ${record.type}.${op.field} is a ${relationship.definition.kind}`);
2409
+ }
2410
+ })(isHasMany(relationship)) : {};
2411
+ if (Array.isArray(value)) {
2412
+ for (let i = 0; i < value.length; i++) {
2413
+ removeRelatedRecord(graph, record, relationship, value[i], op.index ?? null, isRemote);
2414
+ }
2415
+ } else {
2416
+ removeRelatedRecord(graph, record, relationship, value, op.index ?? null, isRemote);
2417
+ }
2418
+ notifyChange(graph, relationship);
2419
+ }
2420
+ function removeRelatedRecord(graph, record, relationship, value, index, isRemote) {
2421
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2422
+ if (!test) {
2423
+ throw new Error(`expected an identifier to remove from the collection relationship`);
2424
+ }
2425
+ })(value) : {};
2426
+ if (_remove(graph, record, relationship, value, index, isRemote)) {
2427
+ removeFromInverse(graph, value, relationship.definition.inverseKey, record, isRemote);
2428
+ }
2429
+ }
2430
+
2431
+ /*
2432
+ This method normalizes a link to an "links object". If the passed link is
2433
+ already an object it's returned without any modifications.
2434
+
2435
+ See http://jsonapi.org/format/#document-links for more information.
2436
+ */
2437
+ function _normalizeLink(link) {
2438
+ switch (typeof link) {
2439
+ case 'object':
2440
+ return link;
2441
+ case 'string':
2442
+ return {
2443
+ href: link
2444
+ };
2445
+ }
2446
+ }
2447
+
2448
+ /*
2449
+ Updates the "canonical" or "remote" state of a relationship, replacing any existing
2450
+ state and blowing away any local changes (excepting new records).
2451
+ */
2452
+ function updateRelationshipOperation(graph, op) {
2453
+ const relationship = graph.get(op.record, op.field);
2454
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2455
+ if (!test) {
2456
+ throw new Error(`Cannot update an implicit relationship`);
2457
+ }
2458
+ })(isHasMany(relationship) || isBelongsTo(relationship)) : {};
2459
+ const {
2460
+ definition,
2461
+ state,
2462
+ identifier
2463
+ } = relationship;
2464
+ const {
2465
+ isCollection
2466
+ } = definition;
2467
+ const payload = op.value;
2468
+ let hasRelationshipDataProperty = false;
2469
+ let hasUpdatedLink = false;
2470
+ if (payload.meta) {
2471
+ relationship.meta = payload.meta;
2472
+ }
2473
+ if (payload.data !== undefined) {
2474
+ hasRelationshipDataProperty = true;
2475
+ if (isCollection) {
2476
+ // TODO deprecate this case. We
2477
+ // have tests saying we support it.
2478
+ if (payload.data === null) {
2479
+ payload.data = [];
2480
+ }
2481
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2482
+ if (!test) {
2483
+ throw new Error(`Expected an array`);
2484
+ }
2485
+ })(Array.isArray(payload.data)) : {};
2486
+ const cache = graph.store.cacheKeyManager;
2487
+ graph.update({
2488
+ op: 'replaceRelatedRecords',
2489
+ record: identifier,
2490
+ field: op.field,
2491
+ value: upgradeIdentifiers(payload.data, cache)
2492
+ }, true);
2493
+ } else {
2494
+ graph.update({
2495
+ op: 'replaceRelatedRecord',
2496
+ record: identifier,
2497
+ field: op.field,
2498
+ value: payload.data ? graph.store.cacheKeyManager.upgradeIdentifier(payload.data) : null
2499
+ }, true);
2500
+ }
2501
+ } else if (definition.isAsync === false && !state.hasReceivedData) {
2502
+ hasRelationshipDataProperty = true;
2503
+ if (isCollection) {
2504
+ graph.update({
2505
+ op: 'replaceRelatedRecords',
2506
+ record: identifier,
2507
+ field: op.field,
2508
+ value: []
2509
+ }, true);
2510
+ } else {
2511
+ graph.update({
2512
+ op: 'replaceRelatedRecord',
2513
+ record: identifier,
2514
+ field: op.field,
2515
+ value: null
2516
+ }, true);
2517
+ }
2518
+ }
2519
+ if (payload.links) {
2520
+ const originalLinks = relationship.links;
2521
+ relationship.links = payload.links;
2522
+ if (payload.links.related) {
2523
+ const relatedLink = _normalizeLink(payload.links.related);
2524
+ const currentLink = originalLinks && originalLinks.related ? _normalizeLink(originalLinks.related) : null;
2525
+ const currentLinkHref = currentLink ? currentLink.href : null;
2526
+ if (relatedLink && relatedLink.href && relatedLink.href !== currentLinkHref) {
2527
+ warn(`You pushed a record of type '${identifier.type}' with a relationship '${definition.key}' configured as 'async: false'. You've included a link but no primary data, this may be an error in your payload. WarpDrive will treat this relationship as known-to-be-empty.`, definition.isAsync || state.hasReceivedData, {
2528
+ id: 'ds.store.push-link-for-sync-relationship'
2529
+ });
2530
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2531
+ if (!test) {
2532
+ throw new Error(`You have pushed a record of type '${identifier.type}' with '${definition.key}' as a link, but the value of that link is not a string.`);
2533
+ }
2534
+ })(typeof relatedLink.href === 'string' || relatedLink.href === null) : {};
2535
+ hasUpdatedLink = true;
2536
+ }
2537
+ }
2538
+ }
2539
+
2540
+ /*
2541
+ Data being pushed into the relationship might contain only data or links,
2542
+ or a combination of both.
2543
+ IF contains only data
2544
+ IF contains both links and data
2545
+ state.isEmpty -> true if is empty array (has-many) or is null (belongs-to)
2546
+ state.hasReceivedData -> true
2547
+ hasDematerializedInverse -> false
2548
+ state.isStale -> false
2549
+ allInverseRecordsAreLoaded -> run-check-to-determine
2550
+ IF contains only links
2551
+ state.isStale -> true
2552
+ */
2553
+ relationship.state.hasFailedLoadAttempt = false;
2554
+ if (hasRelationshipDataProperty) {
2555
+ const relationshipIsEmpty = payload.data === null || Array.isArray(payload.data) && payload.data.length === 0;
2556
+
2557
+ // we don't need to notify here as the update op we pushed in above will notify once
2558
+ // membership is in the correct state.
2559
+ relationship.state.hasReceivedData = true;
2560
+ relationship.state.isStale = false;
2561
+ relationship.state.hasDematerializedInverse = false;
2562
+ relationship.state.isEmpty = relationshipIsEmpty;
2563
+ } else if (hasUpdatedLink) {
2564
+ // only notify stale if we have not previously received membership data.
2565
+ // within this same transaction
2566
+ // this prevents refetching when only one side of the relationship in the
2567
+ // payload contains the info while the other side contains just a link
2568
+ // this only works when the side with just a link is a belongsTo, as we
2569
+ // don't know if a hasMany has full information or not.
2570
+ // see #7049 for context.
2571
+ if (isCollection || !relationship.state.hasReceivedData || isStaleTransaction(relationship.transactionRef, graph._transaction)) {
2572
+ relationship.state.isStale = true;
2573
+ notifyChange(graph, relationship);
2574
+ } else {
2575
+ relationship.state.isStale = false;
2576
+ }
2577
+ }
2578
+ }
2579
+ function isStaleTransaction(relationshipTransactionId, graphTransactionId) {
2580
+ return relationshipTransactionId === 0 ||
2581
+ // relationship has never notified
2582
+ graphTransactionId === null ||
2583
+ // we are not in a transaction
2584
+ relationshipTransactionId < graphTransactionId // we are not part of the current transaction
2585
+ ;
2586
+ }
2587
+ function upgradeIdentifiers(arr, cache) {
2588
+ for (let i = 0; i < arr.length; i++) {
2589
+ arr[i] = cache.upgradeIdentifier(arr[i]);
2590
+ }
2591
+ return arr;
2592
+ }
2593
+ const Graphs = getOrSetGlobal('Graphs', new Map());
2594
+ /*
2595
+ * Graph acts as the cache for relationship data. It allows for
2596
+ * us to ask about and update relationships for a given Identifier
2597
+ * without requiring other objects for that Identifier to be
2598
+ * instantiated (such as `RecordData` or a `Record`)
2599
+ *
2600
+ * This also allows for us to make more substantive changes to relationships
2601
+ * with increasingly minor alterations to other portions of the internals
2602
+ * over time.
2603
+ *
2604
+ * The graph is made up of nodes and edges. Each unique identifier gets
2605
+ * its own node, which is a dictionary with a list of that node's edges
2606
+ * (or connections) to other nodes. In `Model` terms, a node represents a
2607
+ * record instance, with each key (an edge) in the dictionary correlating
2608
+ * to either a `hasMany` or `belongsTo` field on that record instance.
2609
+ *
2610
+ * The value for each key, or `edge` is the identifier(s) the node relates
2611
+ * to in the graph from that key.
2612
+ */
2613
+ class Graph {
2614
+ constructor(store) {
2615
+ this._definitionCache = Object.create(null);
2616
+ this._metaCache = Object.create(null);
2617
+ this._potentialPolymorphicTypes = Object.create(null);
2618
+ this.identifiers = new Map();
2619
+ this.store = store;
2620
+ this._realStore = store._store;
2621
+ this.isDestroyed = false;
2622
+ this._willSyncRemote = false;
2623
+ this._willSyncLocal = false;
2624
+ this._pushedUpdates = {
2625
+ belongsTo: undefined,
2626
+ hasMany: undefined,
2627
+ deletions: []
2628
+ };
2629
+ this._updatedRelationships = new Set();
2630
+ this._transaction = null;
2631
+ this._removing = null;
2632
+ this.silenceNotifications = false;
2633
+ }
2634
+ has(resourceKey, propertyName) {
2635
+ const relationships = this.identifiers.get(resourceKey);
2636
+ if (!relationships) {
2637
+ return false;
2638
+ }
2639
+ return relationships[propertyName] !== undefined;
2640
+ }
2641
+ getDefinition(resourceKey, propertyName) {
2642
+ let defs = this._metaCache[resourceKey.type];
2643
+ let meta = defs?.[propertyName];
2644
+ if (!meta) {
2645
+ const info = /*#__NOINLINE__*/upgradeDefinition(this, resourceKey, propertyName);
2646
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2647
+ if (!test) {
2648
+ throw new Error(`Could not determine relationship information for ${resourceKey.type}.${propertyName}`);
2649
+ }
2650
+ })(info !== null) : {};
2651
+
2652
+ // if (info.rhs_definition?.kind === 'implicit') {
2653
+ // we should possibly also do this
2654
+ // but it would result in being extremely permissive for other relationships by accident
2655
+ // this.registerPolymorphicType(info.rhs_baseModelName, identifier.type);
2656
+ // }
2657
+
2658
+ meta = /*#__NOINLINE__*/isLHS(info, resourceKey.type, propertyName) ? info.lhs_definition : info.rhs_definition;
2659
+ defs = this._metaCache[resourceKey.type] = defs || {};
2660
+ defs[propertyName] = meta;
2661
+ }
2662
+ return meta;
2663
+ }
2664
+ get(resourceKey, propertyName) {
2665
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2666
+ if (!test) {
2667
+ throw new Error(`expected propertyName`);
2668
+ }
2669
+ })(propertyName) : {};
2670
+ let relationships = this.identifiers.get(resourceKey);
2671
+ if (!relationships) {
2672
+ relationships = Object.create(null);
2673
+ this.identifiers.set(resourceKey, relationships);
2674
+ }
2675
+ let relationship = relationships[propertyName];
2676
+ if (!relationship) {
2677
+ const meta = this.getDefinition(resourceKey, propertyName);
2678
+ if (meta.kind === 'belongsTo') {
2679
+ relationship = relationships[propertyName] = createResourceEdge(meta, resourceKey);
2680
+ } else if (meta.kind === 'hasMany') {
2681
+ relationship = relationships[propertyName] = createCollectionEdge(meta, resourceKey);
2682
+ } else {
2683
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2684
+ if (!test) {
2685
+ throw new Error(`Expected kind to be implicit`);
2686
+ }
2687
+ })(meta.kind === 'implicit' && meta.isImplicit === true) : {};
2688
+ relationship = relationships[propertyName] = createImplicitEdge(meta, resourceKey);
2689
+ }
2690
+ }
2691
+ return relationship;
2692
+ }
2693
+ getData(resourceKey, propertyName) {
2694
+ const relationship = this.get(resourceKey, propertyName);
2695
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2696
+ if (!test) {
2697
+ throw new Error(`Cannot getData() on an implicit relationship`);
2698
+ }
2699
+ })(!isImplicit(relationship)) : {};
2700
+ if (isBelongsTo(relationship)) {
2701
+ return legacyGetResourceRelationshipData(relationship, false);
2702
+ }
2703
+ return legacyGetCollectionRelationshipData(relationship, false);
2704
+ }
2705
+ getRemoteData(resourceKey, propertyName) {
2706
+ const relationship = this.get(resourceKey, propertyName);
2707
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2708
+ if (!test) {
2709
+ throw new Error(`Cannot getRemoteData() on an implicit relationship`);
2710
+ }
2711
+ })(!isImplicit(relationship)) : {};
2712
+ if (isBelongsTo(relationship)) {
2713
+ return legacyGetResourceRelationshipData(relationship, true);
2714
+ }
2715
+ return legacyGetCollectionRelationshipData(relationship, true);
2716
+ }
2717
+
2718
+ /*
2719
+ * Allows for the graph to dynamically discover polymorphic connections
2720
+ * without needing to walk prototype chains.
2721
+ *
2722
+ * Used by edges when an added `type` does not match the expected `type`
2723
+ * for that edge.
2724
+ *
2725
+ * Currently we assert before calling this. For a public API we will want
2726
+ * to call out to the schema manager to ask if we should consider these
2727
+ * types as equivalent for a given relationship.
2728
+ */
2729
+ registerPolymorphicType(type1, type2) {
2730
+ const typeCache = this._potentialPolymorphicTypes;
2731
+ let t1 = typeCache[type1];
2732
+ if (!t1) {
2733
+ t1 = typeCache[type1] = Object.create(null);
2734
+ }
2735
+ t1[type2] = true;
2736
+ let t2 = typeCache[type2];
2737
+ if (!t2) {
2738
+ t2 = typeCache[type2] = Object.create(null);
2739
+ }
2740
+ t2[type1] = true;
2741
+ }
2742
+ isReleasable(resourceKey) {
2743
+ const relationships = this.identifiers.get(resourceKey);
2744
+ if (!relationships) {
2745
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_GRAPH)) {
2746
+ if (getGlobalConfig().WarpDrive.debug.LOG_GRAPH || globalThis.getWarpDriveRuntimeConfig().debug.LOG_GRAPH) {
2747
+ // eslint-disable-next-line no-console
2748
+ console.log(`graph: RELEASABLE ${String(resourceKey)}`);
2749
+ }
2750
+ }
2751
+ return true;
2752
+ }
2753
+ const keys = Object.keys(relationships);
2754
+ for (let i = 0; i < keys.length; i++) {
2755
+ const relationship = relationships[keys[i]];
2756
+ // account for previously unloaded relationships
2757
+ // typically from a prior deletion of a record that pointed to this one implicitly
2758
+ if (relationship === undefined) {
2759
+ continue;
2760
+ }
2761
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2762
+ if (!test) {
2763
+ throw new Error(`Expected a relationship`);
2764
+ }
2765
+ })(relationship) : {};
2766
+ if (relationship.definition.inverseIsAsync && !checkIfNew(this._realStore, resourceKey)) {
2767
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_GRAPH)) {
2768
+ if (getGlobalConfig().WarpDrive.debug.LOG_GRAPH || globalThis.getWarpDriveRuntimeConfig().debug.LOG_GRAPH) {
2769
+ // eslint-disable-next-line no-console
2770
+ console.log(`graph: <<NOT>> RELEASABLE ${String(resourceKey)}`);
2771
+ }
2772
+ }
2773
+ return false;
2774
+ }
2775
+ }
2776
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_GRAPH)) {
2777
+ if (getGlobalConfig().WarpDrive.debug.LOG_GRAPH || globalThis.getWarpDriveRuntimeConfig().debug.LOG_GRAPH) {
2778
+ // eslint-disable-next-line no-console
2779
+ console.log(`graph: RELEASABLE ${String(resourceKey)}`);
2780
+ }
2781
+ }
2782
+ return true;
2783
+ }
2784
+ unload(resourceKey, silenceNotifications) {
2785
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_GRAPH)) {
2786
+ if (getGlobalConfig().WarpDrive.debug.LOG_GRAPH || globalThis.getWarpDriveRuntimeConfig().debug.LOG_GRAPH) {
2787
+ // eslint-disable-next-line no-console
2788
+ console.log(`graph: unload ${String(resourceKey)}`);
2789
+ }
2790
+ }
2791
+ const relationships = this.identifiers.get(resourceKey);
2792
+ if (relationships) {
2793
+ // cleans up the graph but retains some nodes
2794
+ // to allow for rematerialization
2795
+ Object.keys(relationships).forEach(key => {
2796
+ const rel = relationships[key];
2797
+ if (!rel) {
2798
+ return;
2799
+ }
2800
+ /*#__NOINLINE__*/
2801
+ destroyRelationship(this, rel, silenceNotifications);
2802
+ if (/*#__NOINLINE__*/isImplicit(rel)) {
2803
+ // @ts-expect-error
2804
+ relationships[key] = undefined;
2805
+ }
2806
+ });
2807
+ }
2808
+ }
2809
+ _isDirty(resourceKey, field) {
2810
+ const relationships = this.identifiers.get(resourceKey);
2811
+ if (!relationships) {
2812
+ return false;
2813
+ }
2814
+ const relationship = relationships[field];
2815
+ if (!relationship) {
2816
+ return false;
2817
+ }
2818
+ if (isBelongsTo(relationship)) {
2819
+ return relationship.localState !== relationship.remoteState;
2820
+ } else if (isHasMany(relationship)) {
2821
+ const hasAdditions = relationship.additions !== null && relationship.additions.size > 0;
2822
+ const hasRemovals = relationship.removals !== null && relationship.removals.size > 0;
2823
+ return hasAdditions || hasRemovals || isReordered(relationship);
2824
+ }
2825
+ return false;
2826
+ }
2827
+ getChanged(resourceKey) {
2828
+ const relationships = this.identifiers.get(resourceKey);
2829
+ const changed = new Map();
2830
+ if (!relationships) {
2831
+ return changed;
2832
+ }
2833
+ const keys = Object.keys(relationships);
2834
+ for (let i = 0; i < keys.length; i++) {
2835
+ const field = keys[i];
2836
+ const relationship = relationships[field];
2837
+ if (!relationship) {
2838
+ continue;
2839
+ }
2840
+ if (isBelongsTo(relationship)) {
2841
+ if (relationship.localState !== relationship.remoteState) {
2842
+ changed.set(field, {
2843
+ kind: 'resource',
2844
+ remoteState: relationship.remoteState,
2845
+ localState: relationship.localState
2846
+ });
2847
+ }
2848
+ } else if (isHasMany(relationship)) {
2849
+ const hasAdditions = relationship.additions !== null && relationship.additions.size > 0;
2850
+ const hasRemovals = relationship.removals !== null && relationship.removals.size > 0;
2851
+ const reordered = isReordered(relationship);
2852
+ if (hasAdditions || hasRemovals || reordered) {
2853
+ changed.set(field, {
2854
+ kind: 'collection',
2855
+ additions: new Set(relationship.additions),
2856
+ removals: new Set(relationship.removals),
2857
+ remoteState: relationship.remoteState,
2858
+ localState: legacyGetCollectionRelationshipData(relationship, false).data || [],
2859
+ reordered
2860
+ });
2861
+ }
2862
+ }
2863
+ }
2864
+ return changed;
2865
+ }
2866
+ hasChanged(resourceKey) {
2867
+ const relationships = this.identifiers.get(resourceKey);
2868
+ if (!relationships) {
2869
+ return false;
2870
+ }
2871
+ const keys = Object.keys(relationships);
2872
+ for (let i = 0; i < keys.length; i++) {
2873
+ if (this._isDirty(resourceKey, keys[i])) {
2874
+ return true;
2875
+ }
2876
+ }
2877
+ return false;
2878
+ }
2879
+ rollback(resourceKey) {
2880
+ const relationships = this.identifiers.get(resourceKey);
2881
+ const changed = [];
2882
+ if (!relationships) {
2883
+ return changed;
2884
+ }
2885
+ const keys = Object.keys(relationships);
2886
+ for (let i = 0; i < keys.length; i++) {
2887
+ const field = keys[i];
2888
+ const relationship = relationships[field];
2889
+ if (!relationship) {
2890
+ continue;
2891
+ }
2892
+ if (this._isDirty(resourceKey, field)) {
2893
+ rollbackRelationship(this, resourceKey, field, relationship);
2894
+ changed.push(field);
2895
+ }
2896
+ }
2897
+ return changed;
2898
+ }
2899
+ remove(resourceKey) {
2900
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_GRAPH)) {
2901
+ if (getGlobalConfig().WarpDrive.debug.LOG_GRAPH || globalThis.getWarpDriveRuntimeConfig().debug.LOG_GRAPH) {
2902
+ // eslint-disable-next-line no-console
2903
+ console.log(`graph: remove ${String(resourceKey)}`);
2904
+ }
2905
+ }
2906
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2907
+ if (!test) {
2908
+ throw new Error(`Cannot remove ${String(resourceKey)} while still removing ${String(this._removing)}`);
2909
+ }
2910
+ })(!this._removing) : {};
2911
+ this._removing = resourceKey;
2912
+ this.unload(resourceKey);
2913
+ this.identifiers.delete(resourceKey);
2914
+ this._removing = null;
2915
+ }
2916
+
2917
+ /*
2918
+ * Remote state changes
2919
+ */
2920
+ push(op) {
2921
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_GRAPH)) {
2922
+ if (getGlobalConfig().WarpDrive.debug.LOG_GRAPH || globalThis.getWarpDriveRuntimeConfig().debug.LOG_GRAPH) {
2923
+ // eslint-disable-next-line no-console
2924
+ console.log(`graph: push ${String(op.record)}`, op);
2925
+ }
2926
+ }
2927
+ if (op.op === 'deleteRecord') {
2928
+ this._pushedUpdates.deletions.push(op);
2929
+ } else {
2930
+ const definition = this.getDefinition(op.record, op.field);
2931
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2932
+ if (!test) {
2933
+ throw new Error(`Cannot push a remote update for an implicit relationship`);
2934
+ }
2935
+ })(definition.kind !== 'implicit') : {};
2936
+ addPending(this._pushedUpdates, definition, op);
2937
+ }
2938
+ if (!this._willSyncRemote) {
2939
+ this._willSyncRemote = true;
2940
+ const store = getStore(this.store);
2941
+ if (!store._cbs) {
2942
+ store._run(() => this._flushRemoteQueue());
2943
+ } else {
2944
+ store._schedule('coalesce', () => this._flushRemoteQueue());
2945
+ }
2946
+ }
2947
+ }
2948
+
2949
+ /*
2950
+ * Local state changes
2951
+ */
2952
+
2953
+ update(op, isRemote = false) {
2954
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2955
+ if (!test) {
2956
+ throw new Error(`Cannot update an implicit relationship`);
2957
+ }
2958
+ })(op.op === 'deleteRecord' || op.op === 'mergeIdentifiers' || !isImplicit(this.get(op.record, op.field))) : {};
2959
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_GRAPH)) {
2960
+ if (getGlobalConfig().WarpDrive.debug.LOG_GRAPH || globalThis.getWarpDriveRuntimeConfig().debug.LOG_GRAPH) {
2961
+ // eslint-disable-next-line no-console
2962
+ console.log(`graph: update (${isRemote ? 'remote' : 'local'}) ${String(op.record)}`, op);
2963
+ }
2964
+ }
2965
+ switch (op.op) {
2966
+ case 'mergeIdentifiers':
2967
+ {
2968
+ const relationships = this.identifiers.get(op.record);
2969
+ if (relationships) {
2970
+ /*#__NOINLINE__*/mergeIdentifier(this, op, relationships);
2971
+ }
2972
+ break;
2973
+ }
2974
+ case 'update':
2975
+ case 'updateRelationship':
2976
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2977
+ if (!test) {
2978
+ throw new Error(`Can only perform the operation updateRelationship on remote state`);
2979
+ }
2980
+ })(isRemote) : {};
2981
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
2982
+ // in debug, assert payload validity eagerly
2983
+ // TODO add deprecations/assertion here for duplicates
2984
+ assertValidRelationshipPayload(this, op);
2985
+ }
2986
+ /*#__NOINLINE__*/
2987
+ updateRelationshipOperation(this, op);
2988
+ break;
2989
+ case 'deleteRecord':
2990
+ {
2991
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2992
+ if (!test) {
2993
+ throw new Error(`Can only perform the operation deleteRelationship on remote state`);
2994
+ }
2995
+ })(isRemote) : {};
2996
+ const identifier = op.record;
2997
+ const relationships = this.identifiers.get(identifier);
2998
+ if (relationships) {
2999
+ Object.keys(relationships).forEach(key => {
3000
+ const rel = relationships[key];
3001
+ if (!rel) {
3002
+ return;
3003
+ }
3004
+ // works together with the has check
3005
+ // @ts-expect-error
3006
+ relationships[key] = undefined;
3007
+ /*#__NOINLINE__*/
3008
+ removeCompletelyFromInverse(this, rel);
3009
+ });
3010
+ this.identifiers.delete(identifier);
3011
+ }
3012
+ break;
3013
+ }
3014
+ case 'replaceRelatedRecord':
3015
+ /*#__NOINLINE__*/replaceRelatedRecord(this, op, isRemote);
3016
+ break;
3017
+ case 'add':
3018
+ /*#__NOINLINE__*/addToRelatedRecords(this, op, isRemote);
3019
+ break;
3020
+ case 'remove':
3021
+ /*#__NOINLINE__*/removeFromRelatedRecords(this, op, isRemote);
3022
+ break;
3023
+ case 'replaceRelatedRecords':
3024
+ /*#__NOINLINE__*/replaceRelatedRecords(this, op, isRemote);
3025
+ break;
3026
+ default:
3027
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
3028
+ {
3029
+ throw new Error(`No local relationship update operation exists for '${op.op}'`);
3030
+ }
3031
+ })() : {};
3032
+ }
3033
+ }
3034
+ _scheduleLocalSync(relationship) {
3035
+ this._updatedRelationships.add(relationship);
3036
+ if (!this._willSyncLocal) {
3037
+ this._willSyncLocal = true;
3038
+ getStore(this.store)._schedule('sync', () => this._flushLocalQueue());
3039
+ }
3040
+ }
3041
+ _flushRemoteQueue() {
3042
+ if (!this._willSyncRemote) {
3043
+ return;
3044
+ }
3045
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_GRAPH)) {
3046
+ if (getGlobalConfig().WarpDrive.debug.LOG_GRAPH || globalThis.getWarpDriveRuntimeConfig().debug.LOG_GRAPH) {
3047
+ // eslint-disable-next-line no-console
3048
+ console.groupCollapsed(`Graph: Initialized Transaction`);
3049
+ }
3050
+ }
3051
+ let transactionRef = peekTransient('transactionRef') ?? 0;
3052
+ this._transaction = ++transactionRef;
3053
+ setTransient('transactionRef', transactionRef);
3054
+ this._willSyncRemote = false;
3055
+ const updates = this._pushedUpdates;
3056
+ const {
3057
+ deletions,
3058
+ hasMany,
3059
+ belongsTo
3060
+ } = updates;
3061
+ updates.deletions = [];
3062
+ updates.hasMany = undefined;
3063
+ updates.belongsTo = undefined;
3064
+ for (let i = 0; i < deletions.length; i++) {
3065
+ this.update(deletions[i], true);
3066
+ }
3067
+ if (hasMany) {
3068
+ flushPending(this, hasMany);
3069
+ }
3070
+ if (belongsTo) {
3071
+ flushPending(this, belongsTo);
3072
+ }
3073
+ this._transaction = null;
3074
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_GRAPH)) {
3075
+ if (getGlobalConfig().WarpDrive.debug.LOG_GRAPH || globalThis.getWarpDriveRuntimeConfig().debug.LOG_GRAPH) {
3076
+ // eslint-disable-next-line no-console
3077
+ console.log(`Graph: transaction finalized`);
3078
+ // eslint-disable-next-line no-console
3079
+ console.groupEnd();
3080
+ }
3081
+ }
3082
+ }
3083
+ _addToTransaction(relationship) {
3084
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
3085
+ if (!test) {
3086
+ throw new Error(`expected a transaction`);
3087
+ }
3088
+ })(this._transaction !== null) : {};
3089
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_GRAPH)) {
3090
+ if (getGlobalConfig().WarpDrive.debug.LOG_GRAPH || globalThis.getWarpDriveRuntimeConfig().debug.LOG_GRAPH) {
3091
+ // eslint-disable-next-line no-console
3092
+ console.log(`Graph: ${String(relationship.identifier)} ${relationship.definition.key} added to transaction`);
3093
+ }
3094
+ }
3095
+ relationship.transactionRef = this._transaction;
3096
+ }
3097
+ _flushLocalQueue() {
3098
+ if (!this._willSyncLocal) {
3099
+ return;
3100
+ }
3101
+ if (this.silenceNotifications) {
3102
+ this.silenceNotifications = false;
3103
+ this._updatedRelationships = new Set();
3104
+ return;
3105
+ }
3106
+ this._willSyncLocal = false;
3107
+ const updated = this._updatedRelationships;
3108
+ this._updatedRelationships = new Set();
3109
+ updated.forEach(rel => notifyChange(this, rel));
3110
+ }
3111
+ destroy() {
3112
+ Graphs.delete(this.store);
3113
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
3114
+ Graphs.delete(getStore(this.store));
3115
+ if (Graphs.size) {
3116
+ Graphs.forEach((_, key) => {
3117
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
3118
+ if (!test) {
3119
+ throw new Error(`Memory Leak Detected, likely the test or app instance previous to this was not torn down properly`);
3120
+ }
3121
+ })(!key.isDestroyed && !key.isDestroying) : {};
3122
+ });
3123
+ }
3124
+ }
3125
+ this.identifiers.clear();
3126
+ this.store = null;
3127
+ this.isDestroyed = true;
3128
+ }
3129
+ }
3130
+ function flushPending(graph, ops) {
3131
+ for (const type of ops.values()) {
3132
+ for (const opList of type.values()) {
3133
+ flushPendingList(graph, opList);
3134
+ }
3135
+ }
3136
+ }
3137
+ function flushPendingList(graph, opList) {
3138
+ for (let i = 0; i < opList.length; i++) {
3139
+ graph.update(opList[i], true);
3140
+ }
3141
+ }
3142
+
3143
+ // Handle dematerialization for relationship `rel`. In all cases, notify the
3144
+ // relationship of the dematerialization: this is done so the relationship can
3145
+ // notify its inverse which needs to update state
3146
+ //
3147
+ // If the inverse is sync, unloading this record is treated as a client-side
3148
+ // delete, so we remove the inverse records from this relationship to
3149
+ // disconnect the graph. Because it's not async, we don't need to keep around
3150
+ // the identifier as an id-wrapper for references
3151
+ function destroyRelationship(graph, rel, silenceNotifications) {
3152
+ if (isImplicit(rel)) {
3153
+ if (graph.isReleasable(rel.identifier)) {
3154
+ /*#__NOINLINE__*/removeCompletelyFromInverse(graph, rel);
3155
+ }
3156
+ return;
3157
+ }
3158
+ const {
3159
+ identifier
3160
+ } = rel;
3161
+ const {
3162
+ inverseKey
3163
+ } = rel.definition;
3164
+ if (!rel.definition.inverseIsImplicit) {
3165
+ /*#__NOINLINE__*/forAllRelatedIdentifiers(rel, inverseIdentifer => /*#__NOINLINE__*/notifyInverseOfDematerialization(graph, inverseIdentifer, inverseKey, identifier, silenceNotifications));
3166
+ }
3167
+ if (!rel.definition.inverseIsImplicit && !rel.definition.inverseIsAsync) {
3168
+ rel.state.isStale = true;
3169
+ /*#__NOINLINE__*/
3170
+ clearRelationship(rel);
3171
+
3172
+ // necessary to clear relationships in the ui from dematerialized records
3173
+ // hasMany is managed by Model which calls `retreiveLatest` after
3174
+ // dematerializing the resource-cache instance.
3175
+ // but sync belongsTo requires this since they don't have a proxy to update.
3176
+ // so we have to notify so it will "update" to null.
3177
+ // we should discuss whether we still care about this, probably fine to just
3178
+ // leave the ui relationship populated since the record is destroyed and
3179
+ // internally we've fully cleaned up.
3180
+ if (!rel.definition.isAsync && !silenceNotifications) {
3181
+ /*#__NOINLINE__*/notifyChange(graph, rel);
3182
+ }
3183
+ }
3184
+ }
3185
+ function notifyInverseOfDematerialization(graph, inverseIdentifier, inverseKey, resourceKey, silenceNotifications) {
3186
+ if (!graph.has(inverseIdentifier, inverseKey)) {
3187
+ return;
3188
+ }
3189
+ const relationship = graph.get(inverseIdentifier, inverseKey);
3190
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
3191
+ if (!test) {
3192
+ throw new Error(`expected no implicit`);
3193
+ }
3194
+ })(!isImplicit(relationship)) : {};
3195
+
3196
+ // For remote members, it is possible that inverseRecordData has already been associated to
3197
+ // to another record. For such cases, do not dematerialize the inverseRecordData
3198
+ if (!isBelongsTo(relationship) || !relationship.localState || resourceKey === relationship.localState) {
3199
+ /*#__NOINLINE__*/removeDematerializedInverse(graph, relationship, resourceKey, silenceNotifications);
3200
+ }
3201
+ }
3202
+ function clearRelationship(relationship) {
3203
+ if (isBelongsTo(relationship)) {
3204
+ relationship.localState = null;
3205
+ relationship.remoteState = null;
3206
+ relationship.state.hasReceivedData = false;
3207
+ relationship.state.isEmpty = true;
3208
+ } else {
3209
+ relationship.remoteMembers.clear();
3210
+ relationship.remoteState = [];
3211
+ relationship.additions = null;
3212
+ relationship.removals = null;
3213
+ relationship.localState = null;
3214
+ }
3215
+ }
3216
+ function removeDematerializedInverse(graph, relationship, inverseIdentifier, silenceNotifications) {
3217
+ if (isBelongsTo(relationship)) {
3218
+ const localInverse = relationship.localState;
3219
+ if (!relationship.definition.isAsync || localInverse && checkIfNew(graph._realStore, localInverse)) {
3220
+ // unloading inverse of a sync relationship is treated as a client-side
3221
+ // delete, so actually remove the models don't merely invalidate the cp
3222
+ // cache.
3223
+ // if the record being unloaded only exists on the client, we similarly
3224
+ // treat it as a client side delete
3225
+ if (relationship.localState === localInverse && localInverse !== null) {
3226
+ relationship.localState = null;
3227
+ }
3228
+ if (relationship.remoteState === localInverse && localInverse !== null) {
3229
+ relationship.remoteState = null;
3230
+ relationship.state.hasReceivedData = true;
3231
+ relationship.state.isEmpty = true;
3232
+ if (relationship.localState && !checkIfNew(graph._realStore, relationship.localState)) {
3233
+ relationship.localState = null;
3234
+ }
3235
+ }
3236
+ } else {
3237
+ relationship.state.hasDematerializedInverse = true;
3238
+ }
3239
+ if (!silenceNotifications) {
3240
+ notifyChange(graph, relationship);
3241
+ }
3242
+ } else {
3243
+ if (!relationship.definition.isAsync || inverseIdentifier && checkIfNew(graph._realStore, inverseIdentifier)) {
3244
+ // unloading inverse of a sync relationship is treated as a client-side
3245
+ // delete, so actually remove the models don't merely invalidate the cp
3246
+ // cache.
3247
+ // if the record being unloaded only exists on the client, we similarly
3248
+ // treat it as a client side delete
3249
+ /*#__NOINLINE__*/
3250
+ removeIdentifierCompletelyFromRelationship(graph, relationship, inverseIdentifier);
3251
+ } else {
3252
+ relationship.state.hasDematerializedInverse = true;
3253
+ }
3254
+ if (!silenceNotifications) {
3255
+ notifyChange(graph, relationship);
3256
+ }
3257
+ }
3258
+ }
3259
+ function removeCompletelyFromInverse(graph, relationship) {
3260
+ const {
3261
+ identifier
3262
+ } = relationship;
3263
+ const {
3264
+ inverseKey
3265
+ } = relationship.definition;
3266
+ forAllRelatedIdentifiers(relationship, inverseIdentifier => {
3267
+ if (graph.has(inverseIdentifier, inverseKey)) {
3268
+ removeIdentifierCompletelyFromRelationship(graph, graph.get(inverseIdentifier, inverseKey), identifier);
3269
+ }
3270
+ });
3271
+ if (isBelongsTo(relationship)) {
3272
+ if (!relationship.definition.isAsync) {
3273
+ clearRelationship(relationship);
3274
+ }
3275
+ relationship.localState = null;
3276
+ } else if (isHasMany(relationship)) {
3277
+ if (!relationship.definition.isAsync) {
3278
+ clearRelationship(relationship);
3279
+ notifyChange(graph, relationship);
3280
+ }
3281
+ } else {
3282
+ relationship.remoteMembers.clear();
3283
+ relationship.localMembers.clear();
3284
+ }
3285
+ }
3286
+ function addPending(cache, definition, op) {
3287
+ const cacheForKind = cache[definition.kind] = cache[definition.kind] || new Map();
3288
+ let cacheForType = cacheForKind.get(definition.inverseType);
3289
+ if (!cacheForType) {
3290
+ cacheForType = new Map();
3291
+ cacheForKind.set(definition.inverseType, cacheForType);
3292
+ }
3293
+ let cacheForField = cacheForType.get(op.field);
3294
+ if (!cacheForField) {
3295
+ cacheForField = [];
3296
+ cacheForType.set(op.field, cacheForField);
3297
+ }
3298
+ cacheForField.push(op);
3299
+ }
3300
+ function isReordered(relationship) {
3301
+ // if we are dirty we are never re-ordered because accessing
3302
+ // the state would flush away any reordering.
3303
+ if (relationship.isDirty) {
3304
+ return false;
3305
+ }
3306
+ const {
3307
+ remoteState,
3308
+ localState,
3309
+ additions,
3310
+ removals
3311
+ } = relationship;
3312
+ if (localState === null) {
3313
+ // the relationship has never been accessed, so it hasn't been reordered either
3314
+ return false;
3315
+ }
3316
+ for (let i = 0, j = 0; i < remoteState.length; i++) {
3317
+ const member = remoteState[i];
3318
+ const localMember = localState[j];
3319
+ if (member !== localMember) {
3320
+ if (removals && removals.has(member)) {
3321
+ // dont increment j because we want to skip this
3322
+ continue;
3323
+ }
3324
+ if (additions && additions.has(localMember)) {
3325
+ // increment j to skip this localMember
3326
+ // decrement i to repeat this remoteMember
3327
+ j++;
3328
+ i--;
3329
+ continue;
3330
+ }
3331
+ return true;
3332
+ }
3333
+
3334
+ // if we made it here, increment j
3335
+ j++;
3336
+ }
3337
+ return false;
3338
+ }
3339
+
3340
+ /**
3341
+ Provides a performance tuned normalized graph for intelligently managing relationships between resources based on identity
3342
+
3343
+ While this Graph is abstract, it currently is a private implementation required as a peer-dependency by the {json:api} Cache Implementation.
3344
+
3345
+ We intend to make this Graph public API after some additional iteration during the 5.x timeframe, until then all APIs should be considered experimental and unstable, not fit for direct application or 3rd party library usage.
3346
+
3347
+ @module
3348
+ */
3349
+
3350
+ function isStore(maybeStore) {
3351
+ return maybeStore._instanceCache !== undefined;
3352
+ }
3353
+ function getWrapper(store) {
3354
+ return isStore(store) ? store._instanceCache._storeWrapper : store;
3355
+ }
3356
+ function peekGraph(store) {
3357
+ return Graphs.get(getWrapper(store));
3358
+ }
3359
+ function graphFor(store) {
3360
+ const wrapper = getWrapper(store);
3361
+ let graph = Graphs.get(wrapper);
3362
+ if (!graph) {
3363
+ graph = new Graph(wrapper);
3364
+ Graphs.set(wrapper, graph);
3365
+ getStore(wrapper)._graph = graph;
3366
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
3367
+ if (getStore(wrapper).isDestroying) {
3368
+ throw new Error(`Memory Leak Detected During Teardown`);
3369
+ }
3370
+ }
3371
+ }
3372
+ return graph;
3373
+ }
3374
+ export { graphFor, isBelongsTo, peekGraph };