@warp-drive/core 5.9.0-beta.1 → 5.9.0-beta.3

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 (277) hide show
  1. package/dist/-private-BL9zXgJB.js +3530 -0
  2. package/dist/-private-BL9zXgJB.js.map +1 -0
  3. package/dist/{-private-DMzvF_Q6.js → -private-Cxa8cMBj.js} +2 -2
  4. package/dist/-private-Cxa8cMBj.js.map +1 -0
  5. package/dist/{unpkg/dev-deprecated/-private-DL4tfrv9.js → -private-xK1KgxZJ.js} +2 -2
  6. package/dist/{-private-b1g4dhl0.js.map → -private-xK1KgxZJ.js.map} +1 -1
  7. package/{declarations/concepts-LHsLJZMl.d.ts → dist/concepts-DFldVwEM.d.ts} +2 -2
  8. package/{declarations/concepts-LHsLJZMl.d.ts.map → dist/concepts-DFldVwEM.d.ts.map} +1 -1
  9. package/dist/configure.js +1 -1
  10. package/dist/graph/-private.d.ts +2 -0
  11. package/dist/graph/-private.js +46 -33
  12. package/dist/graph/-private.js.map +1 -1
  13. package/dist/index.d.ts +2 -0
  14. package/dist/index.js +1 -1
  15. package/{declarations/internal-Cz-893zD.d.ts → dist/internal-DtWOpxrR.d.ts} +2763 -2271
  16. package/dist/internal-DtWOpxrR.d.ts.map +1 -0
  17. package/dist/reactive/-private.d.ts +2 -0
  18. package/dist/reactive/-private.js +1 -1
  19. package/dist/reactive.d.ts +2 -0
  20. package/dist/reactive.js +3 -3
  21. package/{declarations → dist}/record-D3QQcaIR.d.ts.map +1 -1
  22. package/dist/{request--vRFALbQ.js → request-z2NByNx0.js} +2 -2
  23. package/dist/request-z2NByNx0.js.map +1 -0
  24. package/dist/request.d.ts +2 -0
  25. package/dist/request.js +1 -1
  26. package/dist/signals/-leaked.d.ts +1060 -0
  27. package/dist/signals/-leaked.d.ts.map +1 -0
  28. package/dist/signals/-leaked.js +2 -2
  29. package/dist/{src-Dex_phWI.js → src-s5HHjglV.js} +192 -53
  30. package/dist/src-s5HHjglV.js.map +1 -0
  31. package/dist/store/-private.d.ts +2 -0
  32. package/dist/store/-private.js +1 -1
  33. package/dist/store-DNF9Rgoh.js.map +1 -1
  34. package/dist/store.d.ts +2 -0
  35. package/{declarations → dist}/types/-private.d.ts +1 -1
  36. package/{declarations → dist}/types/-private.d.ts.map +1 -1
  37. package/dist/types/-private.js +1 -1
  38. package/dist/types/cache.d.ts +2 -0
  39. package/dist/types/record.js.map +1 -1
  40. package/dist/types/request.d.ts +2 -0
  41. package/dist/types/request.js +1 -1
  42. package/dist/types/request.js.map +1 -1
  43. package/dist/types/runtime.js +1 -1
  44. package/dist/types/schema/concepts.d.ts +2 -0
  45. package/dist/types/schema/fields.js.map +1 -1
  46. package/dist/types/schema/schema-service.d.ts +2 -0
  47. package/dist/types/symbols.js +1 -1
  48. package/dist/types/symbols.js.map +1 -1
  49. package/{declarations → dist}/types.d.ts +1 -1
  50. package/dist/{-private-b1g4dhl0.js → unpkg/dev/-private-BGCYELwo.js} +2 -2
  51. package/dist/unpkg/{dev-deprecated/-private-DL4tfrv9.js.map → dev/-private-BGCYELwo.js.map} +1 -1
  52. package/dist/unpkg/{dev-deprecated/-private-2RfQ2761.js → dev/-private-DhiS6yOR.js} +2 -2
  53. package/dist/unpkg/dev/-private-DhiS6yOR.js.map +1 -0
  54. package/dist/unpkg/dev/-private-pNQae3qH.js +3519 -0
  55. package/dist/unpkg/dev/-private-pNQae3qH.js.map +1 -0
  56. package/dist/unpkg/dev/configure.js +1 -1
  57. package/dist/unpkg/dev/graph/-private.js +46 -33
  58. package/dist/unpkg/dev/graph/-private.js.map +1 -1
  59. package/dist/unpkg/dev/index.js +1 -1
  60. package/dist/unpkg/dev/reactive/-private.js +1 -1
  61. package/dist/unpkg/dev/reactive.js +3 -3
  62. package/dist/unpkg/{dev-deprecated/request-DAuXbfYi.js → dev/request-BbbzRou7.js} +2 -2
  63. package/dist/unpkg/dev/request-BbbzRou7.js.map +1 -0
  64. package/dist/unpkg/dev/request.js +1 -1
  65. package/dist/unpkg/dev/{runtime-EoVKAhTv.js → runtime-DoDtzXJb.js} +2 -2
  66. package/dist/unpkg/dev/runtime-DoDtzXJb.js.map +1 -0
  67. package/dist/unpkg/dev/signals/-leaked.js +2 -2
  68. package/dist/unpkg/dev/{src-Bxlr_vue.js → src-Cf7NXXR2.js} +194 -55
  69. package/dist/unpkg/dev/src-Cf7NXXR2.js.map +1 -0
  70. package/dist/unpkg/dev/store/-private.js +1 -1
  71. package/dist/unpkg/{dev-deprecated/store-TcP2H4Af.js → dev/store-DamE3C4y.js} +2 -2
  72. package/dist/unpkg/dev/store-DamE3C4y.js.map +1 -0
  73. package/dist/unpkg/dev/store.js +1 -1
  74. package/dist/unpkg/dev/types/-private.js +1 -1
  75. package/dist/unpkg/dev/types/record.js.map +1 -1
  76. package/dist/unpkg/dev/types/request.js +1 -1
  77. package/dist/unpkg/dev/types/request.js.map +1 -1
  78. package/dist/unpkg/dev/types/runtime.js +1 -1
  79. package/dist/unpkg/dev/types/schema/fields.js.map +1 -1
  80. package/dist/unpkg/dev/types/symbols.js +1 -1
  81. package/dist/unpkg/dev/types/symbols.js.map +1 -1
  82. package/dist/unpkg/{dev/-private-DL4tfrv9.js → dev-deprecated/-private-BGCYELwo.js} +2 -2
  83. package/dist/unpkg/{prod/-private-Z9i0icpE.js.map → dev-deprecated/-private-BGCYELwo.js.map} +1 -1
  84. package/dist/unpkg/{dev/-private-2RfQ2761.js → dev-deprecated/-private-DhiS6yOR.js} +2 -2
  85. package/dist/unpkg/dev-deprecated/-private-DhiS6yOR.js.map +1 -0
  86. package/dist/unpkg/dev-deprecated/-private-pNQae3qH.js +3519 -0
  87. package/dist/unpkg/dev-deprecated/-private-pNQae3qH.js.map +1 -0
  88. package/dist/unpkg/dev-deprecated/configure.js +1 -1
  89. package/dist/unpkg/dev-deprecated/graph/-private.js +47 -34
  90. package/dist/unpkg/dev-deprecated/graph/-private.js.map +1 -1
  91. package/dist/unpkg/dev-deprecated/index.js +1 -1
  92. package/dist/unpkg/dev-deprecated/reactive/-private.js +1 -1
  93. package/dist/unpkg/dev-deprecated/reactive.js +3 -3
  94. package/dist/unpkg/{dev/request-DAuXbfYi.js → dev-deprecated/request-BbbzRou7.js} +2 -2
  95. package/dist/unpkg/dev-deprecated/request-BbbzRou7.js.map +1 -0
  96. package/dist/unpkg/dev-deprecated/request.js +1 -1
  97. package/dist/unpkg/dev-deprecated/{runtime-BacZMq1r.js → runtime-CPL2BGgT.js} +2 -2
  98. package/dist/unpkg/dev-deprecated/runtime-CPL2BGgT.js.map +1 -0
  99. package/dist/unpkg/dev-deprecated/signals/-leaked.js +2 -2
  100. package/dist/unpkg/dev-deprecated/{src-DEl2Ca3T.js → src-CSuFUXv4.js} +195 -56
  101. package/dist/unpkg/dev-deprecated/src-CSuFUXv4.js.map +1 -0
  102. package/dist/unpkg/dev-deprecated/store/-private.js +1 -1
  103. package/dist/unpkg/{dev/store-DmiFvT1B.js → dev-deprecated/store-Bsdz5mRe.js} +2 -2
  104. package/dist/unpkg/dev-deprecated/store-Bsdz5mRe.js.map +1 -0
  105. package/dist/unpkg/dev-deprecated/store.js +1 -1
  106. package/dist/unpkg/dev-deprecated/types/-private.js +1 -1
  107. package/dist/unpkg/dev-deprecated/types/record.js.map +1 -1
  108. package/dist/unpkg/dev-deprecated/types/request.js +1 -1
  109. package/dist/unpkg/dev-deprecated/types/request.js.map +1 -1
  110. package/dist/unpkg/dev-deprecated/types/runtime.js +1 -1
  111. package/dist/unpkg/dev-deprecated/types/schema/fields.js.map +1 -1
  112. package/dist/unpkg/dev-deprecated/types/symbols.js +1 -1
  113. package/dist/unpkg/dev-deprecated/types/symbols.js.map +1 -1
  114. package/dist/unpkg/prod/-private-8gd8hbwm.js +22 -0
  115. package/dist/unpkg/{prod-deprecated/-private-Z9i0icpE.js.map → prod/-private-8gd8hbwm.js.map} +1 -1
  116. package/dist/unpkg/prod/{-private-BK71-uXR.js → -private-B6aLbrgV.js} +2 -2
  117. package/dist/unpkg/prod/-private-B6aLbrgV.js.map +1 -0
  118. package/dist/unpkg/prod/-private-ggVX_Iob.js +3294 -0
  119. package/dist/unpkg/prod/-private-ggVX_Iob.js.map +1 -0
  120. package/dist/unpkg/prod/configure.js +1 -1
  121. package/dist/unpkg/prod/graph/-private.js +45 -32
  122. package/dist/unpkg/prod/graph/-private.js.map +1 -1
  123. package/dist/unpkg/prod/index.js +1 -1
  124. package/dist/unpkg/prod/reactive/-private.js +1 -1
  125. package/dist/unpkg/prod/reactive.js +3 -3
  126. package/dist/unpkg/prod/{request-BcJNzSgv.js → request-BoeppjDj.js} +2 -2
  127. package/dist/unpkg/prod/request-BoeppjDj.js.map +1 -0
  128. package/dist/unpkg/prod/request.js +1 -1
  129. package/dist/unpkg/prod/signals/-leaked.js +2 -2
  130. package/dist/unpkg/prod/{src-Dzz-j6pp.js → src-C0wuASrN.js} +196 -53
  131. package/dist/unpkg/prod/src-C0wuASrN.js.map +1 -0
  132. package/dist/unpkg/prod/store/-private.js +1 -1
  133. package/dist/unpkg/prod/store-BWhmb7Ob.js.map +1 -1
  134. package/dist/unpkg/prod/types/-private.js +1 -1
  135. package/dist/unpkg/prod/types/record.js.map +1 -1
  136. package/dist/unpkg/prod/types/request.js +1 -1
  137. package/dist/unpkg/prod/types/request.js.map +1 -1
  138. package/dist/unpkg/prod/types/runtime.js +1 -1
  139. package/dist/unpkg/prod/types/schema/fields.js.map +1 -1
  140. package/dist/unpkg/prod/types/symbols.js +1 -1
  141. package/dist/unpkg/prod/types/symbols.js.map +1 -1
  142. package/dist/unpkg/prod-deprecated/{-private-Z9i0icpE.js → -private-8gd8hbwm.js} +2 -2
  143. package/dist/unpkg/{dev/-private-DL4tfrv9.js.map → prod-deprecated/-private-8gd8hbwm.js.map} +1 -1
  144. package/dist/unpkg/prod-deprecated/{-private-BK71-uXR.js → -private-B6aLbrgV.js} +2 -2
  145. package/dist/unpkg/prod-deprecated/-private-B6aLbrgV.js.map +1 -0
  146. package/dist/unpkg/prod-deprecated/-private-ggVX_Iob.js +3294 -0
  147. package/dist/unpkg/prod-deprecated/-private-ggVX_Iob.js.map +1 -0
  148. package/dist/unpkg/prod-deprecated/configure.js +1 -1
  149. package/dist/unpkg/prod-deprecated/graph/-private.js +46 -35
  150. package/dist/unpkg/prod-deprecated/graph/-private.js.map +1 -1
  151. package/dist/unpkg/prod-deprecated/index.js +1 -1
  152. package/dist/unpkg/prod-deprecated/reactive/-private.js +1 -1
  153. package/dist/unpkg/prod-deprecated/reactive.js +3 -3
  154. package/dist/unpkg/prod-deprecated/{request-BcJNzSgv.js → request-BoeppjDj.js} +2 -2
  155. package/dist/unpkg/prod-deprecated/request-BoeppjDj.js.map +1 -0
  156. package/dist/unpkg/prod-deprecated/request.js +1 -1
  157. package/dist/unpkg/prod-deprecated/signals/-leaked.js +2 -2
  158. package/dist/unpkg/prod-deprecated/{src-BOifHFQ5.js → src-BXOgNqmz.js} +197 -54
  159. package/dist/unpkg/prod-deprecated/src-BXOgNqmz.js.map +1 -0
  160. package/dist/unpkg/prod-deprecated/store/-private.js +1 -1
  161. package/dist/unpkg/prod-deprecated/store-BWhmb7Ob.js.map +1 -1
  162. package/dist/unpkg/prod-deprecated/types/-private.js +1 -1
  163. package/dist/unpkg/prod-deprecated/types/record.js.map +1 -1
  164. package/dist/unpkg/prod-deprecated/types/request.js +1 -1
  165. package/dist/unpkg/prod-deprecated/types/request.js.map +1 -1
  166. package/dist/unpkg/prod-deprecated/types/runtime.js +1 -1
  167. package/dist/unpkg/prod-deprecated/types/schema/fields.js.map +1 -1
  168. package/dist/unpkg/prod-deprecated/types/symbols.js +1 -1
  169. package/dist/unpkg/prod-deprecated/types/symbols.js.map +1 -1
  170. package/package.json +15 -19
  171. package/declarations/graph/-private.d.ts +0 -2
  172. package/declarations/index.d.ts +0 -2
  173. package/declarations/internal-Cz-893zD.d.ts.map +0 -1
  174. package/declarations/reactive/-private.d.ts +0 -2
  175. package/declarations/reactive.d.ts +0 -2
  176. package/declarations/request.d.ts +0 -2
  177. package/declarations/signals/-leaked.d.ts +0 -63
  178. package/declarations/signals/-leaked.d.ts.map +0 -1
  179. package/declarations/store/-private.d.ts +0 -2
  180. package/declarations/store.d.ts +0 -8358
  181. package/declarations/store.d.ts.map +0 -1
  182. package/declarations/types/cache.d.ts +0 -2
  183. package/declarations/types/request.d.ts +0 -2
  184. package/declarations/types/schema/concepts.d.ts +0 -2
  185. package/declarations/types/schema/schema-service.d.ts +0 -2
  186. package/dist/-private-DMzvF_Q6.js.map +0 -1
  187. package/dist/-private-HjaQ1wp1.js +0 -1695
  188. package/dist/-private-HjaQ1wp1.js.map +0 -1
  189. package/dist/request--vRFALbQ.js.map +0 -1
  190. package/dist/src-Dex_phWI.js.map +0 -1
  191. package/dist/unpkg/dev/-private-2RfQ2761.js.map +0 -1
  192. package/dist/unpkg/dev/-private-CM1zxNws.js +0 -1684
  193. package/dist/unpkg/dev/-private-CM1zxNws.js.map +0 -1
  194. package/dist/unpkg/dev/request-DAuXbfYi.js.map +0 -1
  195. package/dist/unpkg/dev/runtime-EoVKAhTv.js.map +0 -1
  196. package/dist/unpkg/dev/src-Bxlr_vue.js.map +0 -1
  197. package/dist/unpkg/dev/store-DmiFvT1B.js.map +0 -1
  198. package/dist/unpkg/dev-deprecated/-private-2RfQ2761.js.map +0 -1
  199. package/dist/unpkg/dev-deprecated/-private-CM1zxNws.js +0 -1684
  200. package/dist/unpkg/dev-deprecated/-private-CM1zxNws.js.map +0 -1
  201. package/dist/unpkg/dev-deprecated/request-DAuXbfYi.js.map +0 -1
  202. package/dist/unpkg/dev-deprecated/runtime-BacZMq1r.js.map +0 -1
  203. package/dist/unpkg/dev-deprecated/src-DEl2Ca3T.js.map +0 -1
  204. package/dist/unpkg/dev-deprecated/store-TcP2H4Af.js.map +0 -1
  205. package/dist/unpkg/prod/-private-BK71-uXR.js.map +0 -1
  206. package/dist/unpkg/prod/-private-TNaS5Piv.js +0 -1494
  207. package/dist/unpkg/prod/-private-TNaS5Piv.js.map +0 -1
  208. package/dist/unpkg/prod/-private-Z9i0icpE.js +0 -22
  209. package/dist/unpkg/prod/request-BcJNzSgv.js.map +0 -1
  210. package/dist/unpkg/prod/src-Dzz-j6pp.js.map +0 -1
  211. package/dist/unpkg/prod-deprecated/-private-BK71-uXR.js.map +0 -1
  212. package/dist/unpkg/prod-deprecated/-private-TNaS5Piv.js +0 -1494
  213. package/dist/unpkg/prod-deprecated/-private-TNaS5Piv.js.map +0 -1
  214. package/dist/unpkg/prod-deprecated/request-BcJNzSgv.js.map +0 -1
  215. package/dist/unpkg/prod-deprecated/src-BOifHFQ5.js.map +0 -1
  216. /package/{declarations → dist}/aliases-BWYW5EhX.d.ts +0 -0
  217. /package/{declarations → dist}/aliases-BWYW5EhX.d.ts.map +0 -0
  218. /package/{declarations → dist}/build-config/babel-macros.d.ts +0 -0
  219. /package/{declarations → dist}/build-config/canary-features.d.ts +0 -0
  220. /package/{declarations → dist}/build-config/debugging.d.ts +0 -0
  221. /package/{declarations → dist}/build-config/deprecations.d.ts +0 -0
  222. /package/{declarations → dist}/build-config/env.d.ts +0 -0
  223. /package/{declarations → dist}/build-config/macros.d.ts +0 -0
  224. /package/{declarations → dist}/build-config.d.ts +0 -0
  225. /package/{declarations → dist}/change-C7kqv2kW.d.ts +0 -0
  226. /package/{declarations → dist}/change-C7kqv2kW.d.ts.map +0 -0
  227. /package/{declarations → dist}/configure-B_F639tN.d.ts +0 -0
  228. /package/{declarations → dist}/configure-B_F639tN.d.ts.map +0 -0
  229. /package/{declarations → dist}/configure.d.ts +0 -0
  230. /package/{declarations → dist}/document-BEn91SwT.d.ts +0 -0
  231. /package/{declarations → dist}/document-BEn91SwT.d.ts.map +0 -0
  232. /package/{declarations → dist}/error-50OSEhsF.d.ts +0 -0
  233. /package/{declarations → dist}/error-50OSEhsF.d.ts.map +0 -0
  234. /package/{declarations → dist}/fields-FM7peCiM.d.ts +0 -0
  235. /package/{declarations → dist}/fields-FM7peCiM.d.ts.map +0 -0
  236. /package/{declarations → dist}/graph-DLqYXP2z.d.ts +0 -0
  237. /package/{declarations → dist}/graph-DLqYXP2z.d.ts.map +0 -0
  238. /package/{declarations → dist}/identifier-DQnqOSJK.d.ts +0 -0
  239. /package/{declarations → dist}/identifier-DQnqOSJK.d.ts.map +0 -0
  240. /package/{declarations → dist}/json-api-raw-C5APJHHB.d.ts +0 -0
  241. /package/{declarations → dist}/json-api-raw-C5APJHHB.d.ts.map +0 -0
  242. /package/{declarations → dist}/mutations-CqtoGB4t.d.ts +0 -0
  243. /package/{declarations → dist}/mutations-CqtoGB4t.d.ts.map +0 -0
  244. /package/{declarations → dist}/operations-D1qA6r0_.d.ts +0 -0
  245. /package/{declarations → dist}/operations-D1qA6r0_.d.ts.map +0 -0
  246. /package/{declarations → dist}/params-DrEx3bf8.d.ts +0 -0
  247. /package/{declarations → dist}/params-DrEx3bf8.d.ts.map +0 -0
  248. /package/{declarations → dist}/raw-D5hnjiq7.d.ts +0 -0
  249. /package/{declarations → dist}/raw-D5hnjiq7.d.ts.map +0 -0
  250. /package/{declarations → dist}/record-D3QQcaIR.d.ts +0 -0
  251. /package/{declarations → dist}/relationship-CmHzMPKf.d.ts +0 -0
  252. /package/{declarations → dist}/relationship-CmHzMPKf.d.ts.map +0 -0
  253. /package/{declarations → dist}/symbols-DjRDCeX0.d.ts +0 -0
  254. /package/{declarations → dist}/symbols-DjRDCeX0.d.ts.map +0 -0
  255. /package/{declarations → dist}/types/cache/aliases.d.ts +0 -0
  256. /package/{declarations → dist}/types/cache/change.d.ts +0 -0
  257. /package/{declarations → dist}/types/cache/mutations.d.ts +0 -0
  258. /package/{declarations → dist}/types/cache/operations.d.ts +0 -0
  259. /package/{declarations → dist}/types/cache/relationship.d.ts +0 -0
  260. /package/{declarations → dist}/types/graph.d.ts +0 -0
  261. /package/{declarations → dist}/types/identifier.d.ts +0 -0
  262. /package/{declarations → dist}/types/json/raw.d.ts +0 -0
  263. /package/{declarations → dist}/types/params.d.ts +0 -0
  264. /package/{declarations → dist}/types/record.d.ts +0 -0
  265. /package/{declarations → dist}/types/runtime.d.ts +0 -0
  266. /package/{declarations → dist}/types/runtime.d.ts.map +0 -0
  267. /package/{declarations → dist}/types/schema/fields.d.ts +0 -0
  268. /package/{declarations → dist}/types/schema/fields.type-test.d.ts +0 -0
  269. /package/{declarations → dist}/types/spec/document.d.ts +0 -0
  270. /package/{declarations → dist}/types/spec/error.d.ts +0 -0
  271. /package/{declarations → dist}/types/spec/json-api-raw.d.ts +0 -0
  272. /package/{declarations → dist}/types/symbols.d.ts +0 -0
  273. /package/{declarations → dist}/types/utils.d.ts +0 -0
  274. /package/{declarations → dist}/utils/string.d.ts +0 -0
  275. /package/{declarations → dist}/utils/string.d.ts.map +0 -0
  276. /package/{declarations → dist}/utils-BtURiy8l.d.ts +0 -0
  277. /package/{declarations → dist}/utils-BtURiy8l.d.ts.map +0 -0
@@ -0,0 +1,3294 @@
1
+ import { a as setTransient, r as peekTransient, t as getOrSetGlobal } from "./-private-B6aLbrgV.js";
2
+ import { f as setPromiseResult, o as DOMError, u as getPromiseResult } from "./request-BoeppjDj.js";
3
+
4
+ //#region src/signals/reactivity/configure.ts
5
+ const ARRAY_SIGNAL = getOrSetGlobal("#[]", Symbol("#[]"));
6
+ const OBJECT_SIGNAL = getOrSetGlobal("#{}", Symbol("#{}"));
7
+ /**
8
+ * An Opaque type that represents a framework specific or TC39 signal.
9
+ *
10
+ * It may be an array of signals or a single signal.
11
+ *
12
+ * @private
13
+ */
14
+ /**
15
+ * The hooks which MUST be configured in order to use reactive arrays,
16
+ * resources and documents with framework specfic signals or TC39 signals.
17
+ *
18
+ * Support for multiple frameworks simultaneously can be done via
19
+ * this abstraction by returning multiple signals from the `createSignal`
20
+ * method, and consuming the correct one via the correct framework via
21
+ * the `consumeSignal` and `notifySignal` methods.
22
+ *
23
+ * Unlike many signals implementations, WarpDrive does not wrap values as
24
+ * signals directly, but instead uses signals to alert the reactive layer
25
+ * to changes in the underlying cache. E.g. a signal is associated to a value,
26
+ * but does not serve as the cache for that value directly. We refer to this as
27
+ * a "gate", the pattern has also been called "side-signals".
28
+ *
29
+ * A no-op implementation is allowed, though it may lead to performance issues
30
+ * in locations that use createMemo as no memoization would be done. This is
31
+ * typically desirable only when integrating with a framework that does its own
32
+ * memoization and does not integrate with any signals-like primitive. For these
33
+ * scenarios you may also be interested in integrating with the {@link NotificationManager}
34
+ * more directly.
35
+ *
36
+ * @public
37
+ */
38
+ /**
39
+ * Contains information a {@link SignalHooks} implementation may want
40
+ * to use, such as the specialized key used for the signal
41
+ * representing an array's contents / length.
42
+ *
43
+ * ```ts
44
+ * interface HooksOptions {
45
+ * wellknown: {
46
+ * Array: symbol | string;
47
+ * }
48
+ * }
49
+ * ```
50
+ *
51
+ * @public
52
+ */
53
+ /**
54
+ * Configures the signals implementation to use. Supports multiple
55
+ * implementations simultaneously.
56
+ *
57
+ * See {@link HooksOptions} for the options passed to the provided function
58
+ * when called.
59
+ *
60
+ * See {@link SignalHooks} for the implementation the callback function should
61
+ * return.
62
+ *
63
+ * @public
64
+ * @param buildConfig - a function that takes options and returns a configuration object
65
+ */
66
+ function setupSignals(buildConfig) {
67
+ const hooks = buildConfig({ wellknown: { Array: ARRAY_SIGNAL } });
68
+ setTransient("signalHooks", hooks);
69
+ }
70
+ /**
71
+ * Internal method for consuming the configured `createSignal` hook
72
+ *
73
+ * @private
74
+ */
75
+ function createSignal(obj, key) {
76
+ return peekTransient("signalHooks").createSignal(obj, key);
77
+ }
78
+ /**
79
+ * Internal method for consuming the configured `consumeSignal` hook
80
+ *
81
+ * @private
82
+ */
83
+ function consumeSignal(signal) {
84
+ return peekTransient("signalHooks").consumeSignal(signal);
85
+ }
86
+ /**
87
+ * Internal method for consuming the configured `notifySignal` hook
88
+ *
89
+ * @private
90
+ */
91
+ function notifySignal(signal) {
92
+ return peekTransient("signalHooks").notifySignal(signal);
93
+ }
94
+ function createMemo(object, key, fn) {
95
+ return peekTransient("signalHooks").createMemo(object, key, fn);
96
+ }
97
+ function willSyncFlushWatchers() {
98
+ return peekTransient("signalHooks").willSyncFlushWatchers();
99
+ }
100
+ /**
101
+ * Wraps `promise` using the configured {@link SignalHooks.waitFor}, if any,
102
+ * for things like test-waiters. Returns `promise` unchanged if no
103
+ * `waitFor` hook is configured.
104
+ */
105
+ function waitFor(promise) {
106
+ const signalHooks = peekTransient("signalHooks");
107
+ if (signalHooks?.waitFor) return signalHooks.waitFor(promise);
108
+ return promise;
109
+ }
110
+
111
+ //#endregion
112
+ //#region src/signals/reactivity/internal.ts
113
+ const INITIALIZER_PROTO = { isInitializer: true };
114
+ /**
115
+ * Wraps `fn` so that a signal can recognize it as a lazy initializer
116
+ * for its value rather than the value itself, deferring the call to
117
+ * `fn` until the signal is first accessed.
118
+ */
119
+ function makeInitializer(fn) {
120
+ return Object.assign(Object.create(INITIALIZER_PROTO), { value: fn });
121
+ }
122
+ function isInitializer(obj) {
123
+ return typeof obj === "object" && obj !== null && Object.getPrototypeOf(obj) === INITIALIZER_PROTO;
124
+ }
125
+ /**
126
+ * A WarpDriveSignal is a wrapper around a framework specific or TC39 signal
127
+ * that enables us to store and manage the signal in a universal way.
128
+ *
129
+ * WarpDrive uses signals to manage three separate concepts:
130
+ *
131
+ * - as a `storage` for a value local to the object that we want to be reactive
132
+ * (see `@local` schema field for an example)
133
+ * - as a `gate` for a memoized getter that we want to act as a reactive property
134
+ * but whose value is computed/pulled from a non-reactive source elsewhere
135
+ * and whose latest value is stored in the signal
136
+ * (see `field` schema field for an example)
137
+ * - as a `gate` with a manually managed value updated on pull when `isStale` is true
138
+ *
139
+ *
140
+ * It offers
141
+ *
142
+ * - a non-reactive way to access/update the current value
143
+ * - a non-reactive way to mark the signal as dirtied
144
+ * - a non-reactive way to store content for why the signal was dirtied
145
+ * - access to the underlying Signal(s) in-use
146
+ *
147
+ * For debugging:
148
+ * - the "key" or "name" of the signal
149
+ * - the "object identity" or "context" to which the signal is attached
150
+ *
151
+ * @private
152
+ */
153
+ /**
154
+ * We attach signals to their context object via
155
+ * a Map attached to the object via this symbol.
156
+ *
157
+ * This allows us to store multiple signals
158
+ * on the same object with smaller memory
159
+ * overhead and no WeakMap lookups.
160
+ *
161
+ * Performance sensitive objects should
162
+ * pre-warm their shape by assigning this
163
+ * during initialization.
164
+ *
165
+ * ```ts
166
+ * initializeSignalStore(obj);
167
+ * ```
168
+ *
169
+ * @private
170
+ */
171
+ const Signals = getOrSetGlobal("Signals", Symbol("Signals"));
172
+ /**
173
+ * A type util to recast the object as having a signal store.
174
+ *
175
+ * @private
176
+ */
177
+ function upgradeWithSignals(obj) {}
178
+ /**
179
+ * A util that will create a signal store on the object
180
+ * if it does not already exist and returns the associated
181
+ * signal store.
182
+ *
183
+ * @private
184
+ */
185
+ function withSignalStore(obj) {
186
+ /* @__PURE__ */ upgradeWithSignals(obj);
187
+ if (!obj[Signals]) initializeSignalStore(obj);
188
+ return obj[Signals];
189
+ }
190
+ /**
191
+ * A util that will create a signal store on the object
192
+ * if it does not already exist.
193
+ *
194
+ * Useful for pre-warming the shape of an object to ensure
195
+ * a key-transition to add it is not required later.
196
+ *
197
+ * @private
198
+ */
199
+ function initializeSignalStore(obj) {
200
+ /* @__PURE__ */ upgradeWithSignals(obj);
201
+ obj[Signals] = /* @__PURE__ */ new Map();
202
+ }
203
+ function createInternalSignal(signals, obj, key, initialValue) {
204
+ const warpDriveSignal = {
205
+ key,
206
+ context: obj,
207
+ signal: createSignal(obj, key),
208
+ value: isInitializer(initialValue) ? initialValue.value.call(obj) : initialValue,
209
+ isStale: false
210
+ };
211
+ signals.set(key, warpDriveSignal);
212
+ return warpDriveSignal;
213
+ }
214
+ function getOrCreateInternalSignal(signals, obj, key, initialValue) {
215
+ let signal = peekInternalSignal(signals, key);
216
+ if (!signal) signal = createInternalSignal(signals, obj, key, initialValue);
217
+ return signal;
218
+ }
219
+ function createInternalMemo(signals, object, key, fn) {
220
+ {
221
+ const memo = createMemo(object, key, fn);
222
+ signals.set(key, memo);
223
+ return memo;
224
+ }
225
+ }
226
+ /**
227
+ * Looks up the {@link WarpDriveSignal} stored for `key` in `signals`,
228
+ * if one has already been created, without creating or consuming it.
229
+ */
230
+ function peekInternalSignal(signals, key) {
231
+ return signals?.get(key);
232
+ }
233
+ function consumeInternalSignal(signal) {
234
+ TrackingFrame?.signals.add(signal);
235
+ consumeSignal(signal.signal);
236
+ }
237
+ /**
238
+ * Marks `signal` as stale and notifies its underlying framework/TC39
239
+ * signal, scheduling any of its consumers for re-render/re-computation.
240
+ */
241
+ function notifyInternalSignal(signal) {
242
+ if (signal) {
243
+ signal.isStale = true;
244
+ notifySignal(signal.signal);
245
+ }
246
+ }
247
+ let TrackingFrame = null;
248
+
249
+ //#endregion
250
+ //#region src/signals/reactivity/signal.ts
251
+ /**
252
+ * Creates a signal for the key/object pairing and subscribes to the signal.
253
+ *
254
+ * Use when you need to ensure a signal exists and is subscribed to.
255
+ *
256
+ * @private
257
+ */
258
+ function entangleSignal(signals, obj, key, initialValue) {
259
+ let internalSignal = peekInternalSignal(signals, key);
260
+ if (!internalSignal) internalSignal = createInternalSignal(signals, obj, key, initialValue);
261
+ consumeInternalSignal(internalSignal);
262
+ return internalSignal;
263
+ }
264
+ function entangleInitiallyStaleSignal(signals, obj, key, initialValue) {
265
+ let internalSignal = peekInternalSignal(signals, key);
266
+ if (!internalSignal) {
267
+ internalSignal = createInternalSignal(signals, obj, key, initialValue);
268
+ internalSignal.isStale = true;
269
+ }
270
+ consumeInternalSignal(internalSignal);
271
+ return internalSignal;
272
+ }
273
+ function createSignalDescriptor(key, intialValue) {
274
+ return {
275
+ enumerable: true,
276
+ configurable: false,
277
+ get() {
278
+ const internalSignal = entangleSignal(withSignalStore(this), this, key, intialValue);
279
+ internalSignal.isStale = false;
280
+ return internalSignal.value;
281
+ },
282
+ set(value) {
283
+ const signals = withSignalStore(this);
284
+ const internalSignal = getOrCreateInternalSignal(signals, this, key, intialValue);
285
+ if (internalSignal.value !== value) {
286
+ internalSignal.value = value;
287
+ notifyInternalSignal(internalSignal);
288
+ }
289
+ }
290
+ };
291
+ }
292
+ /**
293
+ * define an enumerable signal property.
294
+ *
295
+ * Akin to Object.defineProperty.
296
+ *
297
+ * The signal will be lazily created when accessed and scoped to the
298
+ * instance of the object.
299
+ *
300
+ * @private
301
+ */
302
+ function defineSignal(obj, key, v) {
303
+ Object.defineProperty(obj, key, createSignalDescriptor(key, v));
304
+ }
305
+ /**
306
+ * Define a non-enumerable signal property.
307
+ *
308
+ * @private
309
+ */
310
+ function defineNonEnumerableSignal(obj, key, v) {
311
+ const desc = createSignalDescriptor(key, v);
312
+ desc.enumerable = false;
313
+ Object.defineProperty(obj, key, desc);
314
+ }
315
+ /**
316
+ * Decorator version of creating a signal.
317
+ */
318
+ function signal(target, key, descriptor) {
319
+ return createSignalDescriptor(key, descriptor.initializer ? makeInitializer(descriptor.initializer) : null);
320
+ }
321
+ /**
322
+ * Decorator version of creating a memoized getter
323
+ */
324
+ function memoized(target, key, descriptor) {
325
+ const getter = descriptor.get;
326
+ descriptor.get = function() {
327
+ const signals = withSignalStore(this);
328
+ let memoSignal = signals.get(key);
329
+ if (!memoSignal) memoSignal = createInternalMemo(signals, this, key, getter.bind(this));
330
+ return memoSignal();
331
+ };
332
+ return descriptor;
333
+ }
334
+ /**
335
+ * Decorator version of creating a gate.
336
+ *
337
+ * @private
338
+ */
339
+ function gate(_target, key, desc) {
340
+ const getter = desc.get;
341
+ const setter = desc.set;
342
+ const isLocal = desc.isLocal;
343
+ desc.get = function() {
344
+ const signals = withSignalStore(this);
345
+ let internalSignal = peekInternalSignal(signals, key);
346
+ if (!internalSignal) internalSignal = createInternalSignal(signals, this, key, getter.call(this));
347
+ else if (internalSignal.isStale) {
348
+ internalSignal.isStale = false;
349
+ internalSignal.value = getter.call(this);
350
+ }
351
+ consumeInternalSignal(internalSignal);
352
+ return internalSignal.value;
353
+ };
354
+ if (setter) desc.set = function(v) {
355
+ const signals = withSignalStore(this);
356
+ let internalSignal = peekInternalSignal(signals, key);
357
+ if (!internalSignal) {
358
+ internalSignal = createInternalSignal(signals, this, key, void 0);
359
+ internalSignal.isStale = true;
360
+ }
361
+ setter.call(this, v);
362
+ if (isLocal) {
363
+ internalSignal.isStale = true;
364
+ notifyInternalSignal(internalSignal);
365
+ }
366
+ };
367
+ return desc;
368
+ }
369
+ /**
370
+ * Defines a reactive "gated" property on `obj` using `desc` as its
371
+ * getter/setter descriptor.
372
+ *
373
+ * Unlike a signal defined with {@link defineSignal}, a gated property's
374
+ * consumers are not notified when the property is set, since its update
375
+ * is expected to be controlled externally (for instance, by a signal it
376
+ * derives its value from) unless the descriptor opts into being locally
377
+ * managed.
378
+ *
379
+ * Akin to `Object.defineProperty`.
380
+ *
381
+ * @private
382
+ */
383
+ function defineGate(obj, key, desc) {
384
+ const options = Object.assign({
385
+ enumerable: true,
386
+ configurable: false
387
+ }, gate(obj, key, desc));
388
+ Object.defineProperty(obj, key, options);
389
+ }
390
+
391
+ //#endregion
392
+ //#region src/signals/request-state.ts
393
+ const RequestCache = /* @__PURE__ */ new WeakMap();
394
+ function isAbortError(error) {
395
+ return error instanceof DOMError && error.name === "AbortError";
396
+ }
397
+ function upgradeLoadingState(state) {
398
+ return state;
399
+ }
400
+ async function watchStream(stream, loadingState) {
401
+ const state = upgradeLoadingState(loadingState);
402
+ const reader = stream.getReader();
403
+ let bytesLoaded = 0;
404
+ let shouldForward = state._stream !== null && state._stream.readable.locked;
405
+ let isForwarding = shouldForward;
406
+ let writer = state._stream?.writable.getWriter();
407
+ const buffer = [];
408
+ state._isPending = false;
409
+ state._isStarted = true;
410
+ state._startTime = performance.now();
411
+ while (true) {
412
+ const { value, done } = await reader.read();
413
+ if (done) break;
414
+ bytesLoaded += value.byteLength;
415
+ state._bytesLoaded = bytesLoaded;
416
+ state._lastPacketTime = performance.now();
417
+ shouldForward = shouldForward || state._stream !== null && state._stream.readable.locked;
418
+ if (shouldForward) {
419
+ if (!isForwarding) {
420
+ isForwarding = true;
421
+ writer = state._stream.writable.getWriter();
422
+ for (const item of buffer) {
423
+ await writer.ready;
424
+ await writer.write(item);
425
+ }
426
+ buffer.length = 0;
427
+ }
428
+ await writer.ready;
429
+ await writer.write(value);
430
+ } else buffer.push(value);
431
+ }
432
+ if (isForwarding) {
433
+ await writer.ready;
434
+ await writer.close();
435
+ } else if (state._stream) {
436
+ await state._stream.readable.cancel("The Stream Has Already Ended");
437
+ state._stream = null;
438
+ }
439
+ state._endTime = performance.now();
440
+ state._isComplete = true;
441
+ state._isStarted = false;
442
+ }
443
+ /**
444
+ * Lazily consumes the stream of a request, providing a number of
445
+ * reactive properties that can be used to build UIs that respond
446
+ * to the progress of a request.
447
+ *
448
+ * @hideconstructor
449
+ */
450
+ var RequestLoadingState = class {
451
+ /** @internal */
452
+ /** @internal */
453
+ /** @internal */
454
+ /** @internal */
455
+ /** @internal */
456
+ /** @internal */
457
+ /** @internal */
458
+ /** @internal */
459
+ /** @internal */
460
+ /** @internal */
461
+ /** @internal */
462
+ /** @internal */
463
+ _stream = null;
464
+ /** @internal */
465
+ _future;
466
+ /** @internal */
467
+ _triggered = false;
468
+ /** @internal */
469
+ _trigger() {
470
+ if (this._triggered) return;
471
+ this._triggered = true;
472
+ const promise = this._future.getStream();
473
+ if (promise.sizeHint) this._sizeHint = promise.sizeHint;
474
+ this.promise = promise.then((stream) => {
475
+ if (!stream) {
476
+ this._isPending = false;
477
+ this._isComplete = true;
478
+ return;
479
+ }
480
+ return watchStream(stream, this);
481
+ }, (error) => {
482
+ this._isPending = false;
483
+ this._isStarted = false;
484
+ if (isAbortError(error)) {
485
+ this._isCancelled = true;
486
+ this._isComplete = true;
487
+ }
488
+ this._isErrored = true;
489
+ this._error = error;
490
+ });
491
+ }
492
+ /**
493
+ * Resolves once the stream has finished being consumed, or rejects
494
+ * if the request errors. `null` until first accessed.
495
+ */
496
+ promise = null;
497
+ /**
498
+ * Whether the stream has not yet started being consumed.
499
+ */
500
+ get isPending() {
501
+ this._trigger();
502
+ return this._isPending;
503
+ }
504
+ /**
505
+ * The total size of the response in bytes, if known ahead of time
506
+ * (via a `Content-Length` header or similar).
507
+ */
508
+ get sizeHint() {
509
+ this._trigger();
510
+ return this._sizeHint;
511
+ }
512
+ /**
513
+ * A readable stream of the response content. Accessing this property
514
+ * begins consumption of the underlying request stream.
515
+ */
516
+ get stream() {
517
+ this._trigger();
518
+ if (!this._stream) {
519
+ if (this._isComplete || this._isCancelled || this._isErrored) return null;
520
+ this._stream = new TransformStream();
521
+ }
522
+ return this._stream.readable;
523
+ }
524
+ /**
525
+ * Whether the stream has started being consumed but has not yet completed.
526
+ */
527
+ get isStarted() {
528
+ this._trigger();
529
+ return this._isStarted;
530
+ }
531
+ /**
532
+ * The number of bytes loaded so far.
533
+ */
534
+ get bytesLoaded() {
535
+ this._trigger();
536
+ return this._bytesLoaded;
537
+ }
538
+ /**
539
+ * The `performance.now()` timestamp at which the stream started being consumed.
540
+ */
541
+ get startTime() {
542
+ this._trigger();
543
+ return this._startTime;
544
+ }
545
+ /**
546
+ * The `performance.now()` timestamp at which the stream finished being consumed.
547
+ */
548
+ get endTime() {
549
+ this._trigger();
550
+ return this._endTime;
551
+ }
552
+ /**
553
+ * The `performance.now()` timestamp at which the last chunk of data was received.
554
+ */
555
+ get lastPacketTime() {
556
+ this._trigger();
557
+ return this._lastPacketTime;
558
+ }
559
+ /**
560
+ * Whether the stream has finished being consumed.
561
+ */
562
+ get isComplete() {
563
+ this._trigger();
564
+ return this._isComplete;
565
+ }
566
+ /**
567
+ * Whether the request was aborted before the stream finished being consumed.
568
+ */
569
+ get isCancelled() {
570
+ this._trigger();
571
+ return this._isCancelled;
572
+ }
573
+ /**
574
+ * Whether an error occurred while consuming the stream.
575
+ */
576
+ get isErrored() {
577
+ this._trigger();
578
+ return this._isErrored;
579
+ }
580
+ /**
581
+ * The error that occurred while consuming the stream, if any.
582
+ */
583
+ get error() {
584
+ this._trigger();
585
+ return this._error;
586
+ }
587
+ /**
588
+ * The number of milliseconds elapsed since the stream started being
589
+ * consumed, using the last packet time (or end time, once complete)
590
+ * as the endpoint.
591
+ */
592
+ get elapsedTime() {
593
+ return (this.endTime || this.lastPacketTime) - this.startTime;
594
+ }
595
+ /**
596
+ * The ratio (0 to 1) of {@link RequestLoadingState.bytesLoaded | bytesLoaded}
597
+ * to {@link RequestLoadingState.sizeHint | sizeHint}, or `0` if no size hint is available.
598
+ */
599
+ get completedRatio() {
600
+ return this.sizeHint ? this.bytesLoaded / this.sizeHint : 0;
601
+ }
602
+ /**
603
+ * The inverse of {@link RequestLoadingState.completedRatio | completedRatio}.
604
+ */
605
+ get remainingRatio() {
606
+ return 1 - this.completedRatio;
607
+ }
608
+ /**
609
+ * The total number of milliseconds elapsed between
610
+ * {@link RequestLoadingState.startTime | startTime} and {@link RequestLoadingState.endTime | endTime}.
611
+ */
612
+ get duration() {
613
+ return this.endTime - this.startTime;
614
+ }
615
+ /**
616
+ * The average download speed in bytes per second.
617
+ */
618
+ get speed() {
619
+ return this.bytesLoaded / (this.elapsedTime / 1e3);
620
+ }
621
+ constructor(future) {
622
+ this._future = future;
623
+ }
624
+ /**
625
+ * Aborts the underlying request.
626
+ */
627
+ abort = () => {
628
+ this._future.abort();
629
+ };
630
+ };
631
+ defineNonEnumerableSignal(RequestLoadingState.prototype, "_isPending", true);
632
+ defineNonEnumerableSignal(RequestLoadingState.prototype, "_isStarted", false);
633
+ defineNonEnumerableSignal(RequestLoadingState.prototype, "_isComplete", false);
634
+ defineNonEnumerableSignal(RequestLoadingState.prototype, "_isCancelled", false);
635
+ defineNonEnumerableSignal(RequestLoadingState.prototype, "_isErrored", false);
636
+ defineNonEnumerableSignal(RequestLoadingState.prototype, "_error", null);
637
+ defineNonEnumerableSignal(RequestLoadingState.prototype, "_sizeHint", 0);
638
+ defineNonEnumerableSignal(RequestLoadingState.prototype, "_bytesLoaded", 0);
639
+ defineNonEnumerableSignal(RequestLoadingState.prototype, "_startTime", 0);
640
+ defineNonEnumerableSignal(RequestLoadingState.prototype, "_endTime", 0);
641
+ defineNonEnumerableSignal(RequestLoadingState.prototype, "_lastPacketTime", 0);
642
+ /**
643
+ * The state of a request in the "pending"
644
+ * state. This is the default initial state.
645
+ *
646
+ * Extends the {@link PendingPromise} interface.
647
+ *
648
+ */
649
+ /**
650
+ * The state of a request in the "fulfilled" state.
651
+ * This is the state of a request that has resolved
652
+ * successfully.
653
+ *
654
+ * Extends the {@link ResolvedPromise} interface.
655
+ *
656
+ */
657
+ /**
658
+ * The state of a request in the "rejected" state.
659
+ * This is the state of a request that has rejected
660
+ * with an error.
661
+ *
662
+ * Extends the {@link RejectedPromise} interface.
663
+ *
664
+ */
665
+ /**
666
+ * The state of a request in the "cancelled" state.
667
+ * This is the state of a promise that has been
668
+ * cancelled.
669
+ *
670
+ */
671
+ /**
672
+ * RequestState extends the concept of {@link PromiseState} to provide a reactive
673
+ * wrapper for a request {@link Future} which allows you write declarative code
674
+ * around a Future's control flow.
675
+ *
676
+ * It is useful in both Template and JavaScript contexts, allowing you
677
+ * to quickly derive behaviors and data from pending, error and success
678
+ * states.
679
+ *
680
+ * The key difference between a {@link Promise} and a Future is that Futures provide
681
+ * access to a {@link ReadableStream | stream} of their content, the {@link RequestKey} of the request (if any)
682
+ * as well as the ability to attempt to {@link Future.abort | abort} the request.
683
+ *
684
+ * ```ts
685
+ * interface Future<T> extends Promise<T>> {
686
+ * getStream(): Promise<ReadableStream>;
687
+ * abort(): void;
688
+ * lid: RequestKey | null;
689
+ * }
690
+ * ```
691
+ *
692
+ * These additional APIs allow us to craft even richer state experiences.
693
+ *
694
+ * To get the state of a request, use {@link getRequestState}.
695
+ *
696
+ * See also:
697
+ * - {@link PendingRequest}
698
+ * - {@link ResolvedRequest}
699
+ * - {@link RejectedRequest}
700
+ * - {@link CancelledRequest}
701
+ *
702
+ */
703
+ const RequestStateProto = {};
704
+ function performRefresh(requester, request, isReload) {
705
+ const req = Object.assign({}, request);
706
+ const cacheOptions = Object.assign({}, req.cacheOptions);
707
+ if (isReload) cacheOptions.reload = true;
708
+ else if (isReload === false) {
709
+ delete cacheOptions.reload;
710
+ cacheOptions.backgroundReload = true;
711
+ } else {
712
+ delete cacheOptions.backgroundReload;
713
+ delete cacheOptions.reload;
714
+ }
715
+ req.cacheOptions = cacheOptions;
716
+ return requester.request(req);
717
+ }
718
+ defineSignal(RequestStateProto, "reason", null);
719
+ defineSignal(RequestStateProto, "value", null);
720
+ defineSignal(RequestStateProto, "result", null);
721
+ defineSignal(RequestStateProto, "error", null);
722
+ defineSignal(RequestStateProto, "status", "pending");
723
+ defineSignal(RequestStateProto, "isPending", true);
724
+ defineSignal(RequestStateProto, "isLoading", true);
725
+ defineSignal(RequestStateProto, "isSuccess", false);
726
+ defineSignal(RequestStateProto, "isError", false);
727
+ defineSignal(RequestStateProto, "request", null);
728
+ defineSignal(RequestStateProto, "response", null);
729
+ Object.defineProperty(RequestStateProto, "isCancelled", { get() {
730
+ return this.isError && isAbortError(this.reason);
731
+ } });
732
+ Object.defineProperty(RequestStateProto, "loadingState", { get() {
733
+ if (!this._loadingState) this._loadingState = new RequestLoadingState(this._request);
734
+ return this._loadingState;
735
+ } });
736
+ function createRequestState(future) {
737
+ const state = getPromiseResult(future);
738
+ const promiseState = Object.create(RequestStateProto);
739
+ promiseState._request = future;
740
+ promiseState.reload = () => {
741
+ return performRefresh(future.requester, promiseState.request, true);
742
+ };
743
+ promiseState.refresh = (usePolicy = false) => {
744
+ return performRefresh(future.requester, promiseState.request, usePolicy === true ? null : false);
745
+ };
746
+ if (state) {
747
+ if (state.isError) {
748
+ promiseState.error = state.result;
749
+ promiseState.reason = state.result;
750
+ promiseState.status = "rejected";
751
+ promiseState.isError = true;
752
+ promiseState.isPending = false;
753
+ promiseState.isLoading = false;
754
+ promiseState.request = state.result.request;
755
+ promiseState.response = state.result.response;
756
+ } else {
757
+ promiseState.result = state.result.content;
758
+ promiseState.value = state.result.content;
759
+ promiseState.status = "fulfilled";
760
+ promiseState.isSuccess = true;
761
+ promiseState.isPending = false;
762
+ promiseState.isLoading = false;
763
+ promiseState.request = state.result.request;
764
+ promiseState.response = state.result.response;
765
+ }
766
+ } else future.then((result) => {
767
+ setPromiseResult(future, {
768
+ isError: false,
769
+ result
770
+ });
771
+ promiseState.result = result.content;
772
+ promiseState.value = result.content;
773
+ promiseState.status = "fulfilled";
774
+ promiseState.isSuccess = true;
775
+ promiseState.isPending = false;
776
+ promiseState.isLoading = false;
777
+ promiseState.request = result.request;
778
+ promiseState.response = result.response;
779
+ }, (error) => {
780
+ setPromiseResult(future, {
781
+ isError: true,
782
+ result: error
783
+ });
784
+ promiseState.error = error;
785
+ promiseState.reason = error;
786
+ promiseState.status = "rejected";
787
+ promiseState.isError = true;
788
+ promiseState.isPending = false;
789
+ promiseState.isLoading = false;
790
+ promiseState.request = error.request;
791
+ promiseState.response = error.response;
792
+ });
793
+ return promiseState;
794
+ }
795
+ /**
796
+ * `getRequestState` can be used in both JavaScript and Template contexts.
797
+ *
798
+ * ```ts
799
+ * import { getRequestState } from '@warp-drive/ember';
800
+ *
801
+ * const state = getRequestState(future);
802
+ * ```
803
+ *
804
+ * For instance, we could write a getter on a component that updates whenever
805
+ * the request state advances or the future changes, by combining the function
806
+ * with the use of `@cached`
807
+ *
808
+ * ```ts
809
+ * class Component {
810
+ * @cached
811
+ * get title() {
812
+ * const state = getRequestState(this.args.request);
813
+ * if (state.isPending) {
814
+ * return 'loading...';
815
+ * }
816
+ * if (state.isError) { return null; }
817
+ * return state.result.title;
818
+ * }
819
+ * }
820
+ * ```
821
+ *
822
+ * Or in a template as a helper:
823
+ *
824
+ * ```gjs
825
+ * import { getRequestState } from '@warp-drive/ember';
826
+ *
827
+ * <template>
828
+ * {{#let (getRequestState @request) as |state|}}
829
+ * {{#if state.isPending}}
830
+ * <Spinner />
831
+ * {{else if state.isError}}
832
+ * <ErrorForm @error={{state.error}} />
833
+ * {{else}}
834
+ * <h1>{{state.result.title}}</h1>
835
+ * {{/if}}
836
+ * {{/let}}
837
+ * </template>
838
+ * ```
839
+ *
840
+ * If looking to use in a template, consider also the `<Request />` component
841
+ * which offers a number of additional capabilities for requests *beyond* what
842
+ * `RequestState` provides.
843
+ *
844
+ */
845
+ function getRequestState(future) {
846
+ let state = RequestCache.get(future);
847
+ if (!state) {
848
+ state = createRequestState(future);
849
+ RequestCache.set(future, state);
850
+ }
851
+ return state;
852
+ }
853
+
854
+ //#endregion
855
+ //#region ../../node_modules/.pnpm/decorat_5d4eca388601a94e7fbc656401b751d1/node_modules/decorator-transforms/dist/runtime--fcdnjmJ.js
856
+ const deferred = /* @__PURE__ */ new WeakMap();
857
+ function deferDecorator(proto, prop, desc) {
858
+ let map = deferred.get(proto);
859
+ if (!map) {
860
+ map = /* @__PURE__ */ new Map();
861
+ deferred.set(proto, map);
862
+ }
863
+ map.set(prop, desc);
864
+ }
865
+ function findDeferredDecorator(target, prop) {
866
+ var _a;
867
+ let cursor = target.prototype;
868
+ while (cursor) {
869
+ let desc = (_a = deferred.get(cursor)) == null ? void 0 : _a.get(prop);
870
+ if (desc) return desc;
871
+ cursor = Object.getPrototypeOf(cursor);
872
+ }
873
+ }
874
+ function decorateFieldV2(prototype, prop, decorators, initializer) {
875
+ let desc = {
876
+ configurable: true,
877
+ enumerable: true,
878
+ writable: true,
879
+ initializer: null
880
+ };
881
+ if (initializer) desc.initializer = initializer;
882
+ for (let decorator of decorators) desc = decorator(prototype, prop, desc) || desc;
883
+ if (desc.initializer === void 0) Object.defineProperty(prototype, prop, desc);
884
+ else deferDecorator(prototype, prop, desc);
885
+ }
886
+ function decorateMethodV2(prototype, prop, decorators) {
887
+ let desc = { ...Object.getOwnPropertyDescriptor(prototype, prop) };
888
+ for (let decorator of decorators) desc = decorator(prototype, prop, desc) || desc;
889
+ if (desc.initializer !== void 0) {
890
+ desc.value = desc.initializer ? desc.initializer.call(prototype) : void 0;
891
+ desc.initializer = void 0;
892
+ }
893
+ Object.defineProperty(prototype, prop, desc);
894
+ }
895
+ function initializeDeferredDecorator(target, prop) {
896
+ let desc = findDeferredDecorator(target.constructor, prop);
897
+ if (desc) Object.defineProperty(target, prop, {
898
+ enumerable: desc.enumerable,
899
+ configurable: desc.configurable,
900
+ writable: desc.writable,
901
+ value: desc.initializer ? desc.initializer.call(target) : void 0
902
+ });
903
+ }
904
+
905
+ //#endregion
906
+ //#region src/signals/request-subscription.ts
907
+ const DEFAULT_DEADLINE = 3e4;
908
+ /**
909
+ * A symbol used to dispose of a {@link RequestSubscription} when the
910
+ * component or context using it is torn down.
911
+ */
912
+ const DISPOSE = Symbol.dispose || Symbol.for("dispose");
913
+ /**
914
+ * The individual autorefresh strategies a {@link RequestSubscription}
915
+ * may combine, see {@link AutorefreshBehaviorCombos}.
916
+ */
917
+ /**
918
+ * The value accepted by {@link SubscriptionArgs.autorefresh}: either a
919
+ * boolean, a single {@link AutorefreshBehaviorType}, or a comma-separated
920
+ * combination of up to three of them.
921
+ */
922
+ /**
923
+ * Utilities to assist in recovering from the error.
924
+ */
925
+ /** @deprecated use {@link RecoveryFeatures} */
926
+ /**
927
+ * Utilities for keeping the request fresh
928
+ */
929
+ /**
930
+ * The args accepted by the `<Request />` component.
931
+ */
932
+ /**
933
+ * The args accepted by a {@link RequestSubscription}.
934
+ */
935
+ /**
936
+ * A reactive class
937
+ *
938
+ * @hideconstructor
939
+ */
940
+ var RequestSubscription = class {
941
+ /**
942
+ * Whether the browser reports that the network is online.
943
+ */
944
+ /**
945
+ * Whether the browser reports that the tab is hidden.
946
+ */
947
+ /**
948
+ * Whether the component is currently refreshing the request.
949
+ */
950
+ /**
951
+ * The most recent blocking request that was made, typically
952
+ * the result of a reload.
953
+ *
954
+ * This will never be the original request passed as an arg to
955
+ * the component.
956
+ *
957
+ * @internal
958
+ */
959
+ /**
960
+ * The most recent request that was made, typically due to either a
961
+ * reload or a refresh.
962
+ *
963
+ * This will never be the original request passed as an arg to
964
+ * the component.
965
+ *
966
+ * @internal
967
+ */
968
+ /**
969
+ * The time at which the network was reported as offline.
970
+ *
971
+ * @internal
972
+ */
973
+ /** @internal */
974
+ /** @internal */
975
+ /** @internal */
976
+ /** @internal */
977
+ /** @internal */
978
+ /**
979
+ * The event listener for network status changes,
980
+ * cached to use the reference for removal.
981
+ *
982
+ * @internal
983
+ */
984
+ /**
985
+ * The event listener for visibility status changes,
986
+ * cached to use the reference for removal.
987
+ *
988
+ * @internal
989
+ */
990
+ /**
991
+ * The last request passed as an arg to the component,
992
+ * cached for comparison.
993
+ *
994
+ * @internal
995
+ */
996
+ /**
997
+ * The last query passed as an arg to the component,
998
+ * cached for comparison.
999
+ *
1000
+ * @internal
1001
+ */
1002
+ /** @internal */
1003
+ /** @internal */
1004
+ /** @internal */
1005
+ /**
1006
+ * The Store this subscription subscribes to or the RequestManager
1007
+ * which issues this request.
1008
+ */
1009
+ /**
1010
+ * The Store or RequestManager that the last subscription is attached to.
1011
+ *
1012
+ * This differs from 'store' because a <Request /> may be passed a
1013
+ * request originating from a different store than the <Request />
1014
+ * component would use if it were to issue the request itself.
1015
+ *
1016
+ * @internal
1017
+ */
1018
+ _requester;
1019
+ constructor(store, args) {
1020
+ this._args = args;
1021
+ this.store = store;
1022
+ this._subscribedTo = null;
1023
+ this._subscription = null;
1024
+ this._intervalStart = null;
1025
+ this._invalidated = false;
1026
+ this._nextInterval = null;
1027
+ this._requester = null;
1028
+ this.isDestroyed = false;
1029
+ this[DISPOSE] = _DISPOSE$2;
1030
+ this._installListeners();
1031
+ this._beginPolling();
1032
+ }
1033
+ /**
1034
+ * @internal
1035
+ */
1036
+ async _beginPolling() {
1037
+ try {
1038
+ if (!this.isIdle) await this.request;
1039
+ } catch {} finally {
1040
+ if (!this.isDestroyed) this._scheduleInterval();
1041
+ }
1042
+ }
1043
+ /**
1044
+ * Whether neither a `request` nor a `query` arg was provided, and so
1045
+ * this subscription has nothing to fetch or monitor.
1046
+ */
1047
+ get isIdle() {
1048
+ const { request, query } = this._args;
1049
+ return Boolean(!request && !query);
1050
+ }
1051
+ /**
1052
+ * The set of {@link AutorefreshBehaviorType}s this subscription is
1053
+ * configured to autorefresh for, derived from {@link SubscriptionArgs.autorefresh}.
1054
+ */
1055
+ static {
1056
+ decorateMethodV2(this.prototype, "isIdle", [memoized]);
1057
+ }
1058
+ get autorefreshTypes() {
1059
+ const { autorefresh } = this._args;
1060
+ let types;
1061
+ if (autorefresh === true) types = ["online", "invalid"];
1062
+ else if (typeof autorefresh === "string") types = autorefresh.split(",");
1063
+ else types = [];
1064
+ return new Set(types);
1065
+ }
1066
+ /** @internal */
1067
+ static {
1068
+ decorateMethodV2(this.prototype, "autorefreshTypes", [memoized]);
1069
+ }
1070
+ async _scheduleInterval() {
1071
+ const { autorefreshThreshold } = this._args;
1072
+ if (typeof window === "undefined" || !(typeof autorefreshThreshold === "number" && autorefreshThreshold > 0) || !this.autorefreshTypes.has("interval") || this._intervalStart !== null) return;
1073
+ if (this._latestRequest) {
1074
+ try {
1075
+ await this._latestRequest;
1076
+ } catch {}
1077
+ if (this.isDestroyed) return;
1078
+ }
1079
+ this._intervalStart = Date.now();
1080
+ this._nextInterval = setTimeout(() => {
1081
+ this._maybeUpdate();
1082
+ }, autorefreshThreshold);
1083
+ }
1084
+ /** @internal */
1085
+ _clearInterval() {
1086
+ if (this._nextInterval) {
1087
+ clearTimeout(this._nextInterval);
1088
+ this._intervalStart = null;
1089
+ }
1090
+ }
1091
+ /**
1092
+ * @internal
1093
+ */
1094
+ _updateSubscriptions() {
1095
+ if (this.isIdle) return;
1096
+ const requestId = this._request.lid;
1097
+ if (this._subscribedTo === requestId) return;
1098
+ this._removeSubscriptions();
1099
+ const store = this._getRequester();
1100
+ this._requester = store;
1101
+ if (requestId && isStore(store)) {
1102
+ this._subscribedTo = requestId;
1103
+ this._subscription = store.notifications.subscribe(requestId, (_id, op) => {
1104
+ if (this._isUpdating) return;
1105
+ switch (op) {
1106
+ case "invalidated":
1107
+ if (this.autorefreshTypes.has("invalid")) {
1108
+ this._invalidated = true;
1109
+ this._maybeUpdate();
1110
+ }
1111
+ break;
1112
+ case "state": {
1113
+ const priority = store.requestManager._deduped.get(requestId)?.priority;
1114
+ const state = this.reqState;
1115
+ if (!priority) this.isRefreshing = false;
1116
+ else if (priority.blocking && !state.isLoading) {
1117
+ this.isRefreshing = false;
1118
+ this._maybeUpdate("policy", true);
1119
+ } else this.isRefreshing = true;
1120
+ }
1121
+ }
1122
+ });
1123
+ }
1124
+ }
1125
+ /**
1126
+ * @internal
1127
+ */
1128
+ _removeSubscriptions() {
1129
+ const store = this._requester;
1130
+ if (this._subscription && store && isStore(store)) {
1131
+ store.notifications.unsubscribe(this._subscription);
1132
+ this._subscribedTo = null;
1133
+ this._subscription = null;
1134
+ this._requester = null;
1135
+ }
1136
+ }
1137
+ /**
1138
+ * Install the event listeners for network and visibility changes.
1139
+ *
1140
+ * This is only done in environments that provide a fully-featured global
1141
+ * `window` and/or `document`. Some non-DOM environments (e.g. React Native,
1142
+ * SSR/Node, workers) may provide a `window` global without the APIs we
1143
+ * rely on here (or no `window`/`document` at all), in which case we skip
1144
+ * attaching the corresponding listeners rather than throwing.
1145
+ *
1146
+ * @internal
1147
+ */
1148
+ _installListeners() {
1149
+ const hasWindow = typeof window !== "undefined";
1150
+ const hasDocument = typeof document !== "undefined";
1151
+ const hasWindowEvents = hasWindow && typeof window.addEventListener === "function";
1152
+ const hasDocumentEvents = hasDocument && typeof document.addEventListener === "function";
1153
+ this.isOnline = hasWindow && typeof window.navigator?.onLine === "boolean" ? window.navigator.onLine : true;
1154
+ this._unavailableStart = this.isOnline ? null : Date.now();
1155
+ this.isHidden = hasDocument && typeof document.visibilityState === "string" && document.visibilityState === "hidden";
1156
+ if (hasWindowEvents) {
1157
+ this._onlineChanged = (event) => {
1158
+ this.isOnline = event.type === "online";
1159
+ if (event.type === "offline" && this._unavailableStart === null) this._unavailableStart = Date.now();
1160
+ this._maybeUpdate();
1161
+ };
1162
+ window.addEventListener("online", this._onlineChanged, {
1163
+ passive: true,
1164
+ capture: true
1165
+ });
1166
+ window.addEventListener("offline", this._onlineChanged, {
1167
+ passive: true,
1168
+ capture: true
1169
+ });
1170
+ }
1171
+ if (hasDocumentEvents) {
1172
+ this._backgroundChanged = () => {
1173
+ const isHidden = document.visibilityState === "hidden";
1174
+ this.isHidden = isHidden;
1175
+ if (isHidden && this._unavailableStart === null) this._unavailableStart = Date.now();
1176
+ this._maybeUpdate();
1177
+ };
1178
+ document.addEventListener("visibilitychange", this._backgroundChanged, {
1179
+ passive: true,
1180
+ capture: true
1181
+ });
1182
+ }
1183
+ }
1184
+ /**
1185
+ * If the network is online and the tab is visible, either reload or refresh the request
1186
+ * based on the component's configuration and the requested update mode.
1187
+ *
1188
+ * Valid modes are:
1189
+ *
1190
+ * - `'reload'`: Force a reload of the request.
1191
+ * - `'refresh'`: Refresh the request in the background.
1192
+ * - `'policy'`: Make the request, letting the store's configured CachePolicy decide whether to reload, refresh, or do nothing.
1193
+ * - `undefined`: Make the request using the component's autorefreshBehavior setting if the autorefreshThreshold has passed.
1194
+ *
1195
+ * @internal
1196
+ */
1197
+ _maybeUpdate(mode, silent) {
1198
+ if (this.isIdle) return;
1199
+ const { reqState } = this;
1200
+ if (reqState.isPending) return;
1201
+ if (!Boolean(this.isOnline && !this.isHidden && (mode || this.autorefreshTypes.size))) {
1202
+ if (!silent && mode && mode !== "_invalidated") throw new Error(`Reload not available: the network is not online or the tab is hidden`);
1203
+ return;
1204
+ }
1205
+ const { autorefreshTypes } = this;
1206
+ let shouldAttempt = this._invalidated || Boolean(mode);
1207
+ if (!shouldAttempt && autorefreshTypes.has("online")) {
1208
+ const { _unavailableStart } = this;
1209
+ const { autorefreshThreshold } = this._args;
1210
+ const deadline = typeof autorefreshThreshold === "number" ? autorefreshThreshold : DEFAULT_DEADLINE;
1211
+ shouldAttempt = Boolean(_unavailableStart && Date.now() - _unavailableStart > deadline);
1212
+ }
1213
+ if (!shouldAttempt && autorefreshTypes.has("interval")) {
1214
+ const { _intervalStart } = this;
1215
+ const { autorefreshThreshold } = this._args;
1216
+ if (_intervalStart && typeof autorefreshThreshold === "number" && autorefreshThreshold > 0) shouldAttempt = Boolean(Date.now() - _intervalStart >= autorefreshThreshold);
1217
+ }
1218
+ this._unavailableStart = null;
1219
+ this._invalidated = false;
1220
+ if (shouldAttempt) {
1221
+ this._clearInterval();
1222
+ this._isUpdating = true;
1223
+ const val = (mode === "_invalidated" ? null : mode) ?? this._args.autorefreshBehavior ?? "policy";
1224
+ const requester = this._getRequester();
1225
+ if (!reqState._request.requester) reqState._request.requester = requester;
1226
+ switch (val) {
1227
+ case "reload":
1228
+ this._latestRequest = reqState.reload();
1229
+ break;
1230
+ case "refresh":
1231
+ this._latestRequest = reqState.refresh();
1232
+ break;
1233
+ case "policy": this._latestRequest = reqState.refresh(true);
1234
+ }
1235
+ if (val !== "refresh") this._localRequest = this._latestRequest;
1236
+ this._scheduleInterval();
1237
+ this._latestRequest.finally(() => {
1238
+ this._isUpdating = false;
1239
+ });
1240
+ }
1241
+ }
1242
+ /**
1243
+ * @internal
1244
+ */
1245
+ _getRequester() {
1246
+ if (this._args.request?.requester) return this._args.request.requester;
1247
+ return this.store;
1248
+ }
1249
+ /**
1250
+ * Retry the request, reloading it from the server.
1251
+ */
1252
+ retry = async () => {
1253
+ this._maybeUpdate("reload");
1254
+ await this._localRequest;
1255
+ };
1256
+ /**
1257
+ * Refresh the request, updating it in the background.
1258
+ */
1259
+ refresh = async () => {
1260
+ this._maybeUpdate("refresh");
1261
+ await this._latestRequest;
1262
+ };
1263
+ /**
1264
+ * features to yield to the error slot of a component
1265
+ */
1266
+ get errorFeatures() {
1267
+ return {
1268
+ isHidden: this.isHidden,
1269
+ isOnline: this.isOnline,
1270
+ retry: this.retry
1271
+ };
1272
+ }
1273
+ /**
1274
+ * features to yield to the content slot of a component
1275
+ */
1276
+ static {
1277
+ decorateMethodV2(this.prototype, "errorFeatures", [memoized]);
1278
+ }
1279
+ get contentFeatures() {
1280
+ const feat = {
1281
+ isHidden: this.isHidden,
1282
+ isOnline: this.isOnline,
1283
+ reload: this.retry,
1284
+ refresh: this.refresh,
1285
+ isRefreshing: this.isRefreshing,
1286
+ latestRequest: this._latestRequest
1287
+ };
1288
+ if (feat.isRefreshing) feat.abort = () => {
1289
+ this._latestRequest?.abort();
1290
+ };
1291
+ return feat;
1292
+ }
1293
+ /**
1294
+ * @internal
1295
+ */
1296
+ static {
1297
+ decorateMethodV2(this.prototype, "contentFeatures", [memoized]);
1298
+ }
1299
+ get _request() {
1300
+ const { request, query } = this._args;
1301
+ const { _localRequest, _originalRequest, _originalQuery } = this;
1302
+ if (_localRequest && request === _originalRequest && query === _originalQuery) return _localRequest;
1303
+ this._originalQuery = query;
1304
+ this._originalRequest = request;
1305
+ if (request) return request;
1306
+ return this.store.request(query);
1307
+ }
1308
+ /**
1309
+ * The {@link Future} this subscription is currently monitoring, and
1310
+ * (re-)subscribes to notifications for as a side effect of access.
1311
+ */
1312
+ static {
1313
+ decorateMethodV2(this.prototype, "_request", [memoized]);
1314
+ }
1315
+ get request() {
1316
+ {
1317
+ const request = this._request;
1318
+ this._updateSubscriptions();
1319
+ return request;
1320
+ }
1321
+ }
1322
+ /**
1323
+ * The {@link RequestState} for {@link RequestSubscription.request | request}.
1324
+ */
1325
+ static {
1326
+ decorateMethodV2(this.prototype, "request", [memoized]);
1327
+ }
1328
+ get reqState() {
1329
+ return getRequestState(this.request);
1330
+ }
1331
+ /**
1332
+ * The resolved content of the request, once it has succeeded.
1333
+ */
1334
+ get result() {
1335
+ return this.reqState.result;
1336
+ }
1337
+ };
1338
+ defineSignal(RequestSubscription.prototype, "isOnline", true);
1339
+ defineSignal(RequestSubscription.prototype, "isHidden", false);
1340
+ defineSignal(RequestSubscription.prototype, "isRefreshing", false);
1341
+ defineSignal(RequestSubscription.prototype, "_localRequest", void 0);
1342
+ defineSignal(RequestSubscription.prototype, "_latestRequest", void 0);
1343
+ function isStore(store) {
1344
+ return "requestManager" in store;
1345
+ }
1346
+ /**
1347
+ * Creates a {@link RequestSubscription}, the reactive class powering the
1348
+ * `<Request />` component's autorefresh, retry, and refresh behaviors.
1349
+ */
1350
+ function createRequestSubscription(store, args) {
1351
+ return new RequestSubscription(store, args);
1352
+ }
1353
+ function upgradeSubscription$2(sub) {
1354
+ return sub;
1355
+ }
1356
+ function _DISPOSE$2() {
1357
+ const self = upgradeSubscription$2(this);
1358
+ self.isDestroyed = true;
1359
+ self._removeSubscriptions();
1360
+ self._clearInterval();
1361
+ if (self._onlineChanged && typeof window !== "undefined" && typeof window.removeEventListener === "function") {
1362
+ window.removeEventListener("online", self._onlineChanged, {
1363
+ passive: true,
1364
+ capture: true
1365
+ });
1366
+ window.removeEventListener("offline", self._onlineChanged, {
1367
+ passive: true,
1368
+ capture: true
1369
+ });
1370
+ }
1371
+ if (self._backgroundChanged && typeof document !== "undefined" && typeof document.removeEventListener === "function") document.removeEventListener("visibilitychange", self._backgroundChanged, {
1372
+ passive: true,
1373
+ capture: true
1374
+ });
1375
+ }
1376
+
1377
+ //#endregion
1378
+ //#region src/signals/page-cache.ts
1379
+ const { abs } = Math;
1380
+ /**
1381
+ * Extracts the `data` member of a document type, or the document type itself
1382
+ * when it has no `data` member.
1383
+ */
1384
+ /**
1385
+ * The element type of a collection document's `data` array — the item type an
1386
+ * infinite view renders. See {@link PaginationState.data}.
1387
+ */
1388
+ /** @internal */
1389
+ function getHref(link) {
1390
+ if (!link) return null;
1391
+ if (typeof link === "string") return link;
1392
+ return link.href;
1393
+ }
1394
+ /**
1395
+ * A single page of a paginated collection: its request, its loaded document, and
1396
+ * its links to neighboring pages in the shared page graph.
1397
+ *
1398
+ * Pages are yielded to consumers as `Readonly<PageCache>` — through
1399
+ * {@link PaginationState.activePage}, {@link PaginationState.pages}, and the
1400
+ * relational getters below — to read a page's data and request status when
1401
+ * building pagination UIs:
1402
+ *
1403
+ * ```ts
1404
+ * const page = paginationState.activePage;
1405
+ *
1406
+ * if (page?.isLoading) {
1407
+ * // show a spinner
1408
+ * } else if (page?.isError) {
1409
+ * // show page.reason
1410
+ * } else {
1411
+ * // render page.data
1412
+ * }
1413
+ * ```
1414
+ *
1415
+ * @since 5.9.0
1416
+ * @public
1417
+ * @hideconstructor
1418
+ */
1419
+ var PageCache = class {
1420
+ static {
1421
+ decorateFieldV2(this.prototype, "request", [signal]);
1422
+ }
1423
+ #request = (initializeDeferredDecorator(this, "request"), void 0);
1424
+ /** @internal */
1425
+ /**
1426
+ * The request that loaded (or is loading) this page, or `null` if the page is
1427
+ * known from links but was never requested. Wrap it in a `<Request>` component
1428
+ * to render the page's loading, error, and content states.
1429
+ */
1430
+ static {
1431
+ decorateFieldV2(this.prototype, "state", [signal]);
1432
+ }
1433
+ #state = (initializeDeferredDecorator(this, "state"), void 0);
1434
+ /** @internal */
1435
+ static {
1436
+ decorateFieldV2(this.prototype, "selfLink", [signal]);
1437
+ }
1438
+ #selfLink = (initializeDeferredDecorator(this, "selfLink"), void 0);
1439
+ /** The `self` link of this page — the URL that identifies it in the collection. */
1440
+ static {
1441
+ decorateFieldV2(this.prototype, "prevLink", [signal]);
1442
+ }
1443
+ #prevLink = (initializeDeferredDecorator(this, "prevLink"), void 0);
1444
+ /** The `prev` link of this page, or `null` at the start of the collection. */
1445
+ static {
1446
+ decorateFieldV2(this.prototype, "nextLink", [signal]);
1447
+ }
1448
+ #nextLink = (initializeDeferredDecorator(this, "nextLink"), void 0);
1449
+ /** The `next` link of this page, or `null` at the end of the collection. */
1450
+ static {
1451
+ decorateFieldV2(this.prototype, "firstLink", [signal]);
1452
+ }
1453
+ #firstLink = (initializeDeferredDecorator(this, "firstLink"), void 0);
1454
+ /** The `first` link of the collection, when the response exposed one. */
1455
+ static {
1456
+ decorateFieldV2(this.prototype, "lastLink", [signal]);
1457
+ }
1458
+ #lastLink = (initializeDeferredDecorator(this, "lastLink"), void 0);
1459
+ /** The `last` link of the collection, when the response exposed one. */
1460
+ static {
1461
+ decorateFieldV2(this.prototype, "pageNumber", [signal]);
1462
+ }
1463
+ #pageNumber = (initializeDeferredDecorator(this, "pageNumber"), void 0);
1464
+ /**
1465
+ * The 1-based page number, or `0` when unknown (for example cursor-based
1466
+ * pagination, where pages have no ordinal position). Derived from the
1467
+ * collection's {@link PageHints}.
1468
+ */
1469
+ static {
1470
+ decorateFieldV2(this.prototype, "before", [signal]);
1471
+ }
1472
+ #before = (initializeDeferredDecorator(this, "before"), void 0);
1473
+ /** @internal */
1474
+ static {
1475
+ decorateFieldV2(this.prototype, "after", [signal]);
1476
+ }
1477
+ #after = (initializeDeferredDecorator(this, "after"), void 0);
1478
+ /** @internal */
1479
+ constructor(manager, url) {
1480
+ this.manager = manager;
1481
+ this.pageNumber = 0;
1482
+ this.selfLink = url;
1483
+ }
1484
+ /**
1485
+ * The document this page's request resolved to, or `null` while it has not
1486
+ * resolved.
1487
+ */
1488
+ get value() {
1489
+ return this.state?.value;
1490
+ }
1491
+ /**
1492
+ * The `data` member of the loaded document — the page's items — or `null`
1493
+ * while the page has not loaded.
1494
+ */
1495
+ static {
1496
+ decorateMethodV2(this.prototype, "value", [memoized]);
1497
+ }
1498
+ get data() {
1499
+ return this.value?.data ?? null;
1500
+ }
1501
+ /**
1502
+ * Whether a request has ever been issued for this page. `false` for pages that
1503
+ * are known only from links.
1504
+ */
1505
+ static {
1506
+ decorateMethodV2(this.prototype, "data", [memoized]);
1507
+ }
1508
+ get isRequested() {
1509
+ return Boolean(this.state);
1510
+ }
1511
+ /** Whether this page's request has settled (successfully or with an error). */
1512
+ static {
1513
+ decorateMethodV2(this.prototype, "isRequested", [memoized]);
1514
+ }
1515
+ get isLoaded() {
1516
+ return this.isSuccess || this.isError;
1517
+ }
1518
+ /** Whether this page's request is currently in flight. */
1519
+ static {
1520
+ decorateMethodV2(this.prototype, "isLoaded", [memoized]);
1521
+ }
1522
+ get isLoading() {
1523
+ return Boolean(this.state?.isLoading);
1524
+ }
1525
+ /** Whether this page's request resolved successfully. */
1526
+ static {
1527
+ decorateMethodV2(this.prototype, "isLoading", [memoized]);
1528
+ }
1529
+ get isSuccess() {
1530
+ return Boolean(this.state?.isSuccess);
1531
+ }
1532
+ /** Whether this page's request was cancelled (aborted). */
1533
+ static {
1534
+ decorateMethodV2(this.prototype, "isSuccess", [memoized]);
1535
+ }
1536
+ get isCancelled() {
1537
+ return Boolean(this.state?.isCancelled);
1538
+ }
1539
+ /** Whether this page's request rejected with an error. */
1540
+ static {
1541
+ decorateMethodV2(this.prototype, "isCancelled", [memoized]);
1542
+ }
1543
+ get isError() {
1544
+ return Boolean(this.state?.isError);
1545
+ }
1546
+ /** The error this page's request rejected with, or `null` if it did not reject. */
1547
+ static {
1548
+ decorateMethodV2(this.prototype, "isError", [memoized]);
1549
+ }
1550
+ get reason() {
1551
+ return this.state?.reason ?? null;
1552
+ }
1553
+ /** The page at this page's `prev` link, or `null` at the start of the collection. */
1554
+ static {
1555
+ decorateMethodV2(this.prototype, "reason", [memoized]);
1556
+ }
1557
+ get prev() {
1558
+ const url = this.prevLink;
1559
+ return url ? this.manager.getPageCache(url) : null;
1560
+ }
1561
+ /** The page at this page's `next` link, or `null` at the end of the collection. */
1562
+ static {
1563
+ decorateMethodV2(this.prototype, "prev", [memoized]);
1564
+ }
1565
+ get next() {
1566
+ const url = this.nextLink;
1567
+ return url ? this.manager.getPageCache(url) : null;
1568
+ }
1569
+ /** The first page of the collection, when the response exposed a `first` link. */
1570
+ static {
1571
+ decorateMethodV2(this.prototype, "next", [memoized]);
1572
+ }
1573
+ get first() {
1574
+ const url = this.firstLink;
1575
+ return url ? this.manager.getPageCache(url) : null;
1576
+ }
1577
+ /** The last page of the collection, when the response exposed a `last` link. */
1578
+ static {
1579
+ decorateMethodV2(this.prototype, "first", [memoized]);
1580
+ }
1581
+ get last() {
1582
+ const url = this.lastLink;
1583
+ return url ? this.manager.getPageCache(url) : null;
1584
+ }
1585
+ /** @internal */
1586
+ static {
1587
+ decorateMethodV2(this.prototype, "last", [memoized]);
1588
+ }
1589
+ get isLinked() {
1590
+ return Boolean(this.before || this.after);
1591
+ }
1592
+ /** @internal */
1593
+ static {
1594
+ decorateMethodV2(this.prototype, "isLinked", [memoized]);
1595
+ }
1596
+ async load(request) {
1597
+ try {
1598
+ this.request = request;
1599
+ this.state = getRequestState(this.request);
1600
+ const content = (await this.request).content;
1601
+ const self = getHref(content?.links?.self);
1602
+ const first = getHref(content?.links?.first);
1603
+ const last = getHref(content?.links?.last);
1604
+ const next = getHref(content?.links?.next);
1605
+ const prev = getHref(content?.links?.prev);
1606
+ const pageNumber = this.getPageNumber(content);
1607
+ if (pageNumber) this.pageNumber = pageNumber;
1608
+ const firstPage = first ? this.manager.getPageCache(first) : null;
1609
+ const lastPage = last ? this.manager.getPageCache(last) : null;
1610
+ const prevPage = prev ? this.manager.getPageCache(prev) : null;
1611
+ const nextPage = next ? this.manager.getPageCache(next) : null;
1612
+ if (firstPage) {
1613
+ this.firstLink = first;
1614
+ firstPage.setPageNumber(1);
1615
+ if (!firstPage.after) firstPage.updateLinkage({ after: this });
1616
+ }
1617
+ if (lastPage) {
1618
+ this.lastLink = last;
1619
+ lastPage.setPageNumber(this.manager.totalPages);
1620
+ if (!lastPage.before) lastPage.updateLinkage({ before: this });
1621
+ }
1622
+ if (nextPage) {
1623
+ this.nextLink = next;
1624
+ nextPage.setPageNumber(this.pageNumber + 1);
1625
+ nextPage.updateLinks({ prev: self });
1626
+ }
1627
+ if (prevPage) {
1628
+ this.prevLink = prev;
1629
+ prevPage.setPageNumber(this.pageNumber - 1);
1630
+ prevPage.updateLinks({ next: self });
1631
+ }
1632
+ if (this.isLinked) {
1633
+ if (prevPage) prevPage.updateLinkage({ after: this });
1634
+ if (nextPage) nextPage.updateLinkage({ before: this });
1635
+ } else if (prevPage?.isLinked) {
1636
+ this.updateLinkage({ before: prevPage });
1637
+ if (nextPage) nextPage.updateLinkage({ before: this });
1638
+ } else if (nextPage?.isLinked) {
1639
+ this.updateLinkage({ after: nextPage });
1640
+ if (prevPage) prevPage.updateLinkage({ after: this });
1641
+ } else if ((prevPage || nextPage) && (firstPage || lastPage)) this.lookupLinkage(firstPage, lastPage);
1642
+ else if (prevPage || nextPage) this.updateLinkage({
1643
+ before: prevPage,
1644
+ after: nextPage
1645
+ });
1646
+ return content;
1647
+ } catch {}
1648
+ return null;
1649
+ }
1650
+ /** @internal */
1651
+ updateLinkage({ before, after }) {
1652
+ const leftSide = before ?? after?.before;
1653
+ const rightSide = after ?? before?.after;
1654
+ if (leftSide && leftSide !== this) {
1655
+ leftSide.setAfter(this);
1656
+ this.setBefore(leftSide);
1657
+ }
1658
+ if (rightSide && rightSide !== this) {
1659
+ rightSide.setBefore(this);
1660
+ this.setAfter(rightSide);
1661
+ }
1662
+ }
1663
+ /** @internal */
1664
+ lookupLinkage(firstPage, lastPage) {
1665
+ if (firstPage && lastPage) {
1666
+ if (abs(this.pageNumber - firstPage.pageNumber) <= abs(this.pageNumber - lastPage.pageNumber)) this.lookupLinkageForward(firstPage);
1667
+ else this.lookupLinkageBackwards(lastPage);
1668
+ } else if (firstPage) this.lookupLinkageForward(firstPage);
1669
+ else if (lastPage) this.lookupLinkageBackwards(lastPage);
1670
+ }
1671
+ /** @internal */
1672
+ lookupLinkageForward(page) {
1673
+ while (page.after && page.after.pageNumber < this.pageNumber) page = page.after;
1674
+ this.updateLinkage({ before: page });
1675
+ }
1676
+ /** @internal */
1677
+ lookupLinkageBackwards(page) {
1678
+ while (page.before && page.before.pageNumber > this.pageNumber) page = page.before;
1679
+ this.updateLinkage({ after: page });
1680
+ }
1681
+ /** @internal */
1682
+ setBefore(page) {
1683
+ this.before = page;
1684
+ }
1685
+ /** @internal */
1686
+ setAfter(page) {
1687
+ this.after = page;
1688
+ }
1689
+ /** @internal */
1690
+ getPageNumber(document) {
1691
+ return this.manager.readPageHints(document).currentPage;
1692
+ }
1693
+ /** @internal */
1694
+ updateLinks = ({ prev, next, first, last }) => {
1695
+ if (prev) this.prevLink = prev;
1696
+ if (next) this.nextLink = next;
1697
+ if (first) this.firstLink = first;
1698
+ if (last) this.lastLink = last;
1699
+ };
1700
+ /** @internal */
1701
+ setPageNumber = (pageNumber) => {
1702
+ if (!this.pageNumber) this.pageNumber = pageNumber;
1703
+ };
1704
+ };
1705
+
1706
+ //#endregion
1707
+ //#region src/signals/pagination-cache.ts
1708
+ const PaginationCacheMap = /* @__PURE__ */ new Map();
1709
+ /**
1710
+ * A hint function for extracting the `currentPage` and `totalPages` from a loaded
1711
+ * document, for when the response does not expose these values through the
1712
+ * default `meta` locations. Provided by the consumer via `<Paginate />`'s
1713
+ * `@pageHints` arg:
1714
+ *
1715
+ * ```gts
1716
+ * <Paginate @pageHints={{...}} />
1717
+ * ```
1718
+ *
1719
+ * Since these values are attached to the shared {@link PaginationCache}, the hint is
1720
+ * a property of the *collection*, not the component. Every `<Paginate />` sharing a
1721
+ * collection must provide the same function reference — define it once at module
1722
+ * scope and import it everywhere.
1723
+ *
1724
+ * @since 5.9.0
1725
+ * @public
1726
+ */
1727
+ /**
1728
+ * The default {@link PageHints}. Reads `currentPage`/`page` and `totalPages` from the
1729
+ * document `meta`, matching the behavior used before `pageHints` was configurable.
1730
+ * Used whenever the consumer does not provide a `pageHints` function.
1731
+ *
1732
+ * @since 5.9.0
1733
+ * @public
1734
+ */
1735
+ const defaultPageHints = (document) => {
1736
+ return {
1737
+ currentPage: document.meta?.page ?? document.meta?.currentPage ?? 0,
1738
+ totalPages: document.meta?.totalPages ?? 0
1739
+ };
1740
+ };
1741
+ /**
1742
+ * The global, shared cache for a paginated collection. Keyed by the collection's
1743
+ * `first` (or `self`) link, so that multiple components paging the same collection
1744
+ * share loaded pages, the page graph, and `totalPages`.
1745
+ *
1746
+ * This holds only shared, request-agnostic data. Per-component state (the active
1747
+ * page, navigation) lives on {@link PaginationState}, which is the API consumers
1748
+ * interact with — the cache itself is plumbing shared between the pagination
1749
+ * classes.
1750
+ *
1751
+ * @since 5.9.0
1752
+ * @public
1753
+ * @hideconstructor
1754
+ */
1755
+ var PaginationCache = class {
1756
+ static {
1757
+ decorateFieldV2(this.prototype, "firstPage", [signal]);
1758
+ }
1759
+ #firstPage = (initializeDeferredDecorator(this, "firstPage"), void 0);
1760
+ /**
1761
+ * The cache key this collection is stored under in the module-level cache —
1762
+ * its `first` (or `self`) link. This is the collection's identity: two
1763
+ * requests whose documents resolve to the same key are pages of the same
1764
+ * collection.
1765
+ *
1766
+ * @internal
1767
+ */
1768
+ /** @internal */
1769
+ static {
1770
+ decorateFieldV2(this.prototype, "totalPages", [signal]);
1771
+ }
1772
+ #totalPages = (initializeDeferredDecorator(this, "totalPages"), void 0);
1773
+ /**
1774
+ * The total number of pages in the collection, or `0` when unknown. Consumers
1775
+ * should read this via {@link PaginationState.totalPages}.
1776
+ */
1777
+ static {
1778
+ decorateFieldV2(this.prototype, "isNumbered", [signal]);
1779
+ }
1780
+ #isNumbered = (initializeDeferredDecorator(this, "isNumbered"), void 0);
1781
+ /**
1782
+ * Whether this collection has server-known page numbers. Stays `false` for
1783
+ * cursor-based collections (opaque `prev`/`next`, no index/total), which drives
1784
+ * whether numbered links are produced. Set once a {@link PageHints} yields a real
1785
+ * `currentPage`/`totalPages`.
1786
+ *
1787
+ * @internal
1788
+ */
1789
+ /** @internal */
1790
+ /** @internal */
1791
+ pageHints = defaultPageHints;
1792
+ constructor(key) {
1793
+ this.key = key;
1794
+ this.pagesCache = /* @__PURE__ */ new Map();
1795
+ this.firstPage = null;
1796
+ this.totalPages = 0;
1797
+ this.isNumbered = false;
1798
+ }
1799
+ /**
1800
+ * Installs the consumer-provided {@link PageHints} onto the shared cache. The first
1801
+ * explicit hint wins; passing `undefined` (no hint) is a no-op that preserves the
1802
+ * default. In dev, asserts that components sharing a collection do not provide
1803
+ * diverging hint functions.
1804
+ *
1805
+ * @internal
1806
+ */
1807
+ installPageHints(pageHints) {
1808
+ if (!pageHints) return;
1809
+ if (this.pageHints === defaultPageHints) {
1810
+ this.pageHints = pageHints;
1811
+ return;
1812
+ }
1813
+ }
1814
+ /**
1815
+ * Runs the active {@link PageHints} against a document.
1816
+ *
1817
+ * Both values are *hints*, not requirements. A value of `0` means "unknown" —
1818
+ * the response did not expose it and no `pageHints` function derived it. When a
1819
+ * value is present (`> 0`) it is relied upon (numbered links, total, sparse
1820
+ * placement of jumped-to pages); when absent the page graph falls back to pure
1821
+ * `prev`/`next` adjacency (as in cursor/infinite streams).
1822
+ *
1823
+ * @internal
1824
+ */
1825
+ readPageHints(document) {
1826
+ const { currentPage, totalPages } = this.pageHints(document);
1827
+ if (currentPage > 0 || totalPages > 0) this.isNumbered = true;
1828
+ return {
1829
+ currentPage,
1830
+ totalPages
1831
+ };
1832
+ }
1833
+ /** @internal */
1834
+ getPageCache(url) {
1835
+ let page = this.pagesCache.get(url);
1836
+ if (!page) {
1837
+ page = new PageCache(this, url);
1838
+ this.pagesCache.set(url, page);
1839
+ }
1840
+ return page;
1841
+ }
1842
+ /** @internal */
1843
+ loadPage(url, request) {
1844
+ const page = this.getPageCache(url);
1845
+ if ((!page.isLoaded || page.isError) && request) page.load(request).then((document) => {
1846
+ this.updateFirstPage(page);
1847
+ if (document) this.totalPages = this.getTotalPages(document);
1848
+ });
1849
+ return page;
1850
+ }
1851
+ /** @internal */
1852
+ updateFirstPage(page) {
1853
+ let maybeFirstPage = page;
1854
+ while (maybeFirstPage.before) maybeFirstPage = maybeFirstPage.before;
1855
+ if (!this.firstPage || this.firstPage.pageNumber > maybeFirstPage.pageNumber) this.firstPage = maybeFirstPage;
1856
+ }
1857
+ /** @internal */
1858
+ getTotalPages(document) {
1859
+ return this.readPageHints(document).totalPages;
1860
+ }
1861
+ /**
1862
+ * Every page known to the shared graph, in order — loaded pages and pages
1863
+ * known only from links — across all components sharing the collection.
1864
+ *
1865
+ * This is the whole-collection view. For the run a single component is
1866
+ * viewing, use {@link PaginationState.pages}.
1867
+ *
1868
+ * ```ts
1869
+ * const cache = getPaginationCache(firstLink);
1870
+ * for (const page of cache.pages) {
1871
+ * // page.isLoaded, page.pageNumber, page.data, ...
1872
+ * }
1873
+ * ```
1874
+ */
1875
+ get pages() {
1876
+ const self = this;
1877
+ return { *[Symbol.iterator]() {
1878
+ let page = self.firstPage;
1879
+ while (page) {
1880
+ yield page;
1881
+ page = page.after;
1882
+ }
1883
+ } };
1884
+ }
1885
+ /**
1886
+ * The items of every loaded page in the shared graph, flattened into one
1887
+ * contiguous iterable in page order. Pages that are known but not loaded
1888
+ * contribute nothing.
1889
+ *
1890
+ * This is the whole-collection view. For the run a single component is
1891
+ * viewing, use {@link PaginationState.data}.
1892
+ */
1893
+ static {
1894
+ decorateMethodV2(this.prototype, "pages", [memoized]);
1895
+ }
1896
+ get data() {
1897
+ const self = this;
1898
+ return { *[Symbol.iterator]() {
1899
+ for (const page of self.pages) if (page.data) yield* page.data;
1900
+ } };
1901
+ }
1902
+ static {
1903
+ decorateMethodV2(this.prototype, "data", [memoized]);
1904
+ }
1905
+ };
1906
+ /**
1907
+ * Get the shared {@link PaginationCache} for a given cache key (the collection's
1908
+ * `first` or `self` link). Returns the same instance for the same key for the
1909
+ * lifetime of the module.
1910
+ *
1911
+ * @since 5.9.0
1912
+ * @public
1913
+ */
1914
+ function getPaginationCache(key) {
1915
+ let cache = PaginationCacheMap.get(key);
1916
+ if (!cache) {
1917
+ cache = new PaginationCache(key);
1918
+ PaginationCacheMap.set(key, cache);
1919
+ }
1920
+ return cache;
1921
+ }
1922
+ /**
1923
+ * Clears the module-level pagination cache used by {@link getPaginationCache}.
1924
+ * Primarily intended for test isolation, since the cache is keyed by url and
1925
+ * otherwise persists for the lifetime of the module.
1926
+ *
1927
+ * @since 5.9.0
1928
+ * @public
1929
+ */
1930
+ function clearPaginationCache() {
1931
+ PaginationCacheMap.clear();
1932
+ }
1933
+
1934
+ //#endregion
1935
+ //#region src/signals/pagination-state.ts
1936
+ /**
1937
+ * The two navigation surfaces a `<Paginate />` component can drive. Selecting
1938
+ * one (via the component's `@mode` arg) narrows the yielded state so the two
1939
+ * APIs cannot be mixed:
1940
+ *
1941
+ * - `'paged'` — single-page view, see {@link PagedPaginationState}.
1942
+ * - `'infinite'` — accumulated view, see {@link InfinitePaginationState}.
1943
+ */
1944
+ /**
1945
+ * The part of a {@link PaginationState} available to both navigation surfaces.
1946
+ */
1947
+ /**
1948
+ * The paged (single-page view) surface of a {@link PaginationState}: render
1949
+ * {@link PaginationState.activePageRequest | activePageRequest}, navigate with
1950
+ * {@link PaginationState.loadPage | loadPage}. This is what the `<Paginate />`
1951
+ * component yields in `'paged'` mode (the default).
1952
+ */
1953
+ /**
1954
+ * The infinite (accumulated view) surface of a {@link PaginationState}: render
1955
+ * {@link PaginationState.data | data}, grow it with
1956
+ * {@link PaginationState.loadNext | loadNext}/{@link PaginationState.loadPrev | loadPrev}.
1957
+ * This is what the `<Paginate />` component yields in `'infinite'` mode.
1958
+ */
1959
+ /**
1960
+ * Resolves a {@link PaginateMode} to the surface it exposes, so a component
1961
+ * generic over the mode can yield only that surface.
1962
+ */
1963
+ /**
1964
+ * The per-component, local pagination state. It houses the state that is unique
1965
+ * to a single component instance — the active page and navigation — while
1966
+ * referencing a shared {@link PaginationCache} for the page graph and data.
1967
+ *
1968
+ * This is the object yielded by the `<Paginate />` component, narrowed by the
1969
+ * component's `@mode` arg to one of its two navigation surfaces so the two
1970
+ * APIs cannot be mixed:
1971
+ *
1972
+ * - **Paged** (`@mode="paged"`, the default): {@link PagedPaginationState} —
1973
+ * render {@link activePageRequest}, navigate with {@link loadPage} (what the
1974
+ * numbered/relational links call). Reads {@link activePage}.
1975
+ * - **Infinite** (`@mode="infinite"`): {@link InfinitePaginationState} — render
1976
+ * {@link data}, wrap {@link nextRequest}/{@link previousRequest} in `<Request>`
1977
+ * for loading state, and grow the view with {@link loadNext}/{@link loadPrev}.
1978
+ *
1979
+ * Both surfaces read the same shared page graph; the mode only selects which
1980
+ * API is exposed.
1981
+ *
1982
+ * Instances are created via {@link getPaginationState} (or by the `<Paginate />`
1983
+ * component on your behalf), never constructed directly.
1984
+ *
1985
+ * @since 5.9.0
1986
+ * @public
1987
+ * @hideconstructor
1988
+ */
1989
+ var PaginationState = class {
1990
+ /** @internal */
1991
+ /** @internal */
1992
+ /** @internal */
1993
+ /**
1994
+ * The shared page graph and data this component reads from.
1995
+ *
1996
+ * @internal
1997
+ */
1998
+ /**
1999
+ * The page the paged surface is currently showing. Starts at the page this
2000
+ * component first loaded and moves whenever {@link loadPage} runs (for
2001
+ * example a numbered link is clicked).
2002
+ */
2003
+ /**
2004
+ * The page this component first loaded, used to seed the active page and frontier.
2005
+ *
2006
+ * @internal
2007
+ */
2008
+ /**
2009
+ * The first and last loaded pages of the contiguous run this component is
2010
+ * viewing. Drives the infinite surface — {@link data} walks from
2011
+ * `frontierStart` to `frontierEnd`, and {@link loadPrev}/{@link loadNext} extend
2012
+ * them backward/forward. Both seed to {@link initialPage}; a purely paged
2013
+ * consumer never extends them, so they stay put and are effectively unused.
2014
+ *
2015
+ * @internal
2016
+ */
2017
+ /** @internal */
2018
+ /**
2019
+ * The request of the latest {@link adoptPage} call — only that call may
2020
+ * commit. Later calls (or a {@link loadPage} navigation) claim the slot,
2021
+ * superseding in-flight adoptions so the newest navigation always wins.
2022
+ * Untracked bookkeeping.
2023
+ *
2024
+ * @internal
2025
+ */
2026
+ constructor(request, pageHints) {
2027
+ this.store = request.requester;
2028
+ this.request = request;
2029
+ this.pageHints = pageHints;
2030
+ this._adoptTarget = null;
2031
+ this.setup();
2032
+ }
2033
+ /**
2034
+ * The request for the {@link activePage}, for the paged surface to render. This
2035
+ * is what a single-page view wraps in a `<Request>` to show the active page's
2036
+ * loading, error, and content states:
2037
+ *
2038
+ * ```gts
2039
+ * <Paginate @request={{this.request}}>
2040
+ * <:content as |pages|>
2041
+ * <Request @request={{pages.activePageRequest}}>
2042
+ * <:content as |result|>
2043
+ * {{#each result.data as |item|}}...{{/each}}
2044
+ * </:content>
2045
+ * </Request>
2046
+ * </:content>
2047
+ * </Paginate>
2048
+ * ```
2049
+ */
2050
+ get activePageRequest() {
2051
+ return this.activePage?.request ?? null;
2052
+ }
2053
+ /**
2054
+ * The total number of pages in the collection, or `0` when it is unknown (for
2055
+ * example a cursor-based collection that reports no total).
2056
+ *
2057
+ * ```gts
2058
+ * <p>Page {{pages.activePage.pageNumber}} of {{pages.totalPages}}</p>
2059
+ * ```
2060
+ */
2061
+ static {
2062
+ decorateMethodV2(this.prototype, "activePageRequest", [memoized]);
2063
+ }
2064
+ get totalPages() {
2065
+ return this.paginationCache?.totalPages ?? 0;
2066
+ }
2067
+ /**
2068
+ * The pages of the run this component is viewing, from the backward frontier
2069
+ * to the forward frontier inclusive, in order. Part of the infinite surface:
2070
+ * it is the same run as {@link data}, yielding the {@link PageCache} objects
2071
+ * instead of their flattened items — use it when the UI needs per-page
2072
+ * boundaries or request states.
2073
+ *
2074
+ * Grows as {@link loadNext}/{@link loadPrev} extend the frontier. Scoped to
2075
+ * this component's frontier (not the shared cache), so components paging the
2076
+ * same collection to different extents each see only what they have scrolled
2077
+ * through. For every page known to the whole collection, see
2078
+ * {@link PaginationCache.pages}.
2079
+ */
2080
+ static {
2081
+ decorateMethodV2(this.prototype, "totalPages", [memoized]);
2082
+ }
2083
+ get pages() {
2084
+ const self = this;
2085
+ return { *[Symbol.iterator]() {
2086
+ const end = self.frontierEnd;
2087
+ let page = self.frontierStart;
2088
+ while (page) {
2089
+ yield page;
2090
+ if (page === end) break;
2091
+ page = page.after;
2092
+ }
2093
+ } };
2094
+ }
2095
+ /**
2096
+ * The accumulated items across the loaded run, from the backward frontier to
2097
+ * the forward frontier inclusive — the single set an infinite collection renders.
2098
+ * Grows as {@link loadNext}/{@link loadPrev} extend the frontier. Scoped to this
2099
+ * component's frontier (not the shared cache), so components paging the same
2100
+ * collection to different extents each see only what they have scrolled through.
2101
+ *
2102
+ * The flattened items of {@link pages}, as one contiguous iterable. For the
2103
+ * items of every loaded page in the whole collection, see
2104
+ * {@link PaginationCache.data}.
2105
+ *
2106
+ * ```gts
2107
+ * <Paginate @request={{this.request}} @mode="infinite">
2108
+ * <:content as |pages features|>
2109
+ * {{#each pages.data as |item|}}...{{/each}}
2110
+ * {{#if pages.hasNext}}
2111
+ * <button {{on "click" features.loadNext}}>Load more</button>
2112
+ * {{/if}}
2113
+ * </:content>
2114
+ * </Paginate>
2115
+ * ```
2116
+ */
2117
+ static {
2118
+ decorateMethodV2(this.prototype, "pages", [memoized]);
2119
+ }
2120
+ get data() {
2121
+ const self = this;
2122
+ return { *[Symbol.iterator]() {
2123
+ for (const page of self.pages) if (page.data) yield* page.data;
2124
+ } };
2125
+ }
2126
+ /**
2127
+ * Whether a page exists after the forward frontier — i.e. there is more to load
2128
+ * going forward. Use to hide the trailing load-more sentinel at end-of-list:
2129
+ *
2130
+ * ```gts
2131
+ * {{#if pages.hasNext}}
2132
+ * <button {{on "click" features.loadNext}}>Load more</button>
2133
+ * {{/if}}
2134
+ * ```
2135
+ */
2136
+ static {
2137
+ decorateMethodV2(this.prototype, "data", [memoized]);
2138
+ }
2139
+ get hasNext() {
2140
+ return Boolean(this.frontierEnd?.nextLink);
2141
+ }
2142
+ /**
2143
+ * Whether a page exists before the backward frontier.
2144
+ */
2145
+ static {
2146
+ decorateMethodV2(this.prototype, "hasNext", [memoized]);
2147
+ }
2148
+ get hasPrevious() {
2149
+ return Boolean(this.frontierStart?.prevLink);
2150
+ }
2151
+ /**
2152
+ * The request for the page just after the forward frontier, for the infinite
2153
+ * surface. `null` until {@link loadNext} fires it (so a `<Request>` wrapping it
2154
+ * renders its idle block), the in-flight `Future` while that page loads, then
2155
+ * `null` again once the frontier advances onto it. Also `null` at end-of-list.
2156
+ *
2157
+ * ```gts
2158
+ * {{#if pages.hasNext}}
2159
+ * <Request @request={{pages.nextRequest}}>
2160
+ * <:idle><button {{on "click" features.loadNext}}>Load more</button></:idle>
2161
+ * <:loading><Spinner /></:loading>
2162
+ * </Request>
2163
+ * {{/if}}
2164
+ * ```
2165
+ */
2166
+ static {
2167
+ decorateMethodV2(this.prototype, "hasPrevious", [memoized]);
2168
+ }
2169
+ get nextRequest() {
2170
+ const url = this.frontierEnd?.nextLink;
2171
+ if (!url) return null;
2172
+ return this.paginationCache?.getPageCache(url).request ?? null;
2173
+ }
2174
+ /**
2175
+ * The request for the page just before the backward frontier. Mirror of
2176
+ * {@link nextRequest} for {@link loadPrev}.
2177
+ */
2178
+ static {
2179
+ decorateMethodV2(this.prototype, "nextRequest", [memoized]);
2180
+ }
2181
+ get previousRequest() {
2182
+ const url = this.frontierStart?.prevLink;
2183
+ if (!url) return null;
2184
+ return this.paginationCache?.getPageCache(url).request ?? null;
2185
+ }
2186
+ /** @internal */
2187
+ static {
2188
+ decorateMethodV2(this.prototype, "previousRequest", [memoized]);
2189
+ }
2190
+ async setup() {
2191
+ let document;
2192
+ try {
2193
+ document = await this.request;
2194
+ } catch {
2195
+ return;
2196
+ }
2197
+ const content = document.content;
2198
+ const selfLink = getHref(content.links?.self);
2199
+ const cacheKey = getHref(content.links?.first) ?? selfLink ?? "";
2200
+ const cache = getPaginationCache(cacheKey);
2201
+ cache.installPageHints(this.pageHints);
2202
+ this.paginationCache = cache;
2203
+ cache.totalPages = cache.getTotalPages(content);
2204
+ this.activePage = this.initialPage = cache.loadPage(selfLink, this.request);
2205
+ this.frontierStart = this.frontierEnd = this.initialPage;
2206
+ }
2207
+ /**
2208
+ * Commits a resolved, membership-proven page into this state, making it the
2209
+ * {@link activePage}. The synchronous commit step under {@link adoptPage},
2210
+ * which is where the resolution and membership verification live.
2211
+ *
2212
+ * It only activates the page and keeps the infinite surface's frontier
2213
+ * coherent — a page already inside the run leaves the frontier untouched,
2214
+ * an adjacent page extends it, and a disjoint page resets the run to the
2215
+ * adopted page (jump semantics).
2216
+ *
2217
+ * @internal
2218
+ */
2219
+ _activate(page, url) {
2220
+ this.activePage = page;
2221
+ for (const existing of this.pages) if (existing === page) return;
2222
+ if (this.frontierEnd?.nextLink === url) this.frontierEnd = page;
2223
+ else if (this.frontierStart?.prevLink === url) this.frontierStart = page;
2224
+ else this.frontierStart = this.frontierEnd = page;
2225
+ }
2226
+ /**
2227
+ * Adopts an externally-issued request into this pagination, making its page
2228
+ * the {@link activePage} — the programmatic entry point for route-driven
2229
+ * navigation when managing a `PaginationState` directly (the `<Paginate />`
2230
+ * component uses the same mechanism for a changed `@request` arg).
2231
+ *
2232
+ * Awaits the request and verifies that its document is a page of this
2233
+ * state's collection (same `first` — or `self` — link). On a match, the
2234
+ * page is loaded (a page already in the shared cache is reused) and — once
2235
+ * its request settles — committed: it becomes the active page, and the
2236
+ * infinite surface's run is kept coherent (a page already inside the run
2237
+ * leaves it untouched, an adjacent page extends it, a disjoint page resets
2238
+ * the run to the adopted page). The commit happens only after the page has
2239
+ * loaded, so the previous page stays active — and rendered — while the
2240
+ * adoption resolves. Returns the page's document.
2241
+ *
2242
+ * Concurrent calls race safely: the latest call wins. An earlier in-flight
2243
+ * adoption is superseded and commits nothing, and a {@link loadPage}
2244
+ * navigation also supersedes a pending adoption (the user's click is the
2245
+ * newer intent).
2246
+ *
2247
+ * Returns `null` — leaving the state untouched — whenever the adoption does
2248
+ * not commit:
2249
+ *
2250
+ * - the request (or its page's load) rejected
2251
+ * - the document is a page of a *different* collection
2252
+ * - this state has not finished setting up its own collection yet
2253
+ * - the call was superseded by a newer navigation
2254
+ *
2255
+ * ```ts
2256
+ * const pages = getPaginationState(initialRequest);
2257
+ * // later, e.g. in a route model hook reacting to a ?page= param:
2258
+ * const adopted = await pages.adoptPage(store.request(query));
2259
+ * if (adopted === null) {
2260
+ * // not part of this collection — start a fresh pagination
2261
+ * }
2262
+ * ```
2263
+ *
2264
+ * It is a stable reference, so it is safe to pass around as an "action" or
2265
+ * "event" handler.
2266
+ */
2267
+ adoptPage = async (request) => {
2268
+ this._adoptTarget = request;
2269
+ let content;
2270
+ try {
2271
+ content = (await request).content;
2272
+ } catch {
2273
+ return null;
2274
+ }
2275
+ if (this._adoptTarget !== request) return null;
2276
+ const cache = this.paginationCache;
2277
+ if (!cache) return null;
2278
+ const selfLink = getHref(content.links?.self);
2279
+ const firstLink = getHref(content.links?.first);
2280
+ if (!selfLink || (firstLink ?? selfLink) !== cache.key) return null;
2281
+ const page = cache.loadPage(selfLink, request);
2282
+ try {
2283
+ await page.request;
2284
+ } catch {
2285
+ return null;
2286
+ }
2287
+ if (this._adoptTarget !== request) return null;
2288
+ this._activate(page, selfLink);
2289
+ return page.value;
2290
+ };
2291
+ /**
2292
+ * Extends the backward frontier by one page, prepending it to {@link data}.
2293
+ * The frontier advances only once the page has loaded, so
2294
+ * {@link previousRequest} tracks the in-flight page meanwhile. Returns the
2295
+ * loaded value, or `null` when there is no previous page or the load fails.
2296
+ *
2297
+ * On failure the frontier stays put and {@link previousRequest} keeps
2298
+ * resolving to the failed page, so a wrapping `<Request>` renders its error
2299
+ * block. Calling again retries: the failed page is re-requested with a
2300
+ * forced reload.
2301
+ *
2302
+ * In templates it is also available as the `loadPrev` content feature
2303
+ * ({@link InfinitePaginationContentFeatures.loadPrev}) yielded by
2304
+ * `<Paginate />`; the two are the same function.
2305
+ *
2306
+ * It is a stable reference, so it is safe to pass around as an "action" or
2307
+ * "event" handler.
2308
+ */
2309
+ loadPrev = async () => {
2310
+ return this._extend("prev");
2311
+ };
2312
+ /**
2313
+ * Extends the forward frontier by one page, appending it to {@link data}.
2314
+ * Mirror of {@link loadPrev}.
2315
+ *
2316
+ * In templates it is also available as the `loadNext` content feature
2317
+ * ({@link InfinitePaginationContentFeatures.loadNext}) yielded by
2318
+ * `<Paginate />`; the two are the same function.
2319
+ *
2320
+ * ```gts
2321
+ * <button {{on "click" pages.loadNext}}>Load more</button>
2322
+ * ```
2323
+ */
2324
+ loadNext = async () => {
2325
+ return this._extend("next");
2326
+ };
2327
+ /** @internal */
2328
+ _extend = async (dir) => {
2329
+ const cache = this.paginationCache;
2330
+ const frontier = dir === "next" ? this.frontierEnd : this.frontierStart;
2331
+ const url = dir === "next" ? frontier?.nextLink : frontier?.prevLink;
2332
+ if (!url) return null;
2333
+ const page = cache.getPageCache(url);
2334
+ if (!page.isRequested || page.isError) {
2335
+ const request = this.store.request(page.isError ? {
2336
+ method: "GET",
2337
+ url,
2338
+ cacheOptions: { reload: true }
2339
+ } : {
2340
+ method: "GET",
2341
+ url
2342
+ });
2343
+ cache.loadPage(url, request);
2344
+ }
2345
+ try {
2346
+ await page.request;
2347
+ } catch {
2348
+ return null;
2349
+ }
2350
+ if (dir === "next") this.frontierEnd = page;
2351
+ else this.frontierStart = page;
2352
+ return page.value;
2353
+ };
2354
+ /**
2355
+ * Loads a specific page by its URL and makes it the {@link activePage},
2356
+ * requesting it first if it is not already loaded. This is the paged surface's
2357
+ * navigation entry point, called by the numbered and relational links.
2358
+ *
2359
+ * In templates it is also available as the `loadPage` content feature
2360
+ * ({@link PagedPaginationContentFeatures.loadPage}) yielded by `<Paginate />`;
2361
+ * the two are the same function.
2362
+ *
2363
+ * It is a stable reference, so it is safe to pass around as an "action" or
2364
+ * "event" handler. Returns the page's value, or `null` if it has none or
2365
+ * the load fails.
2366
+ *
2367
+ * On failure the page stays active and {@link activePageRequest} resolves to
2368
+ * it, so a wrapping `<Request>` renders its error block. Calling again (for
2369
+ * example clicking the page's link a second time) retries: the failed page
2370
+ * is re-requested with a forced reload.
2371
+ *
2372
+ * ```gts
2373
+ * <EachLink @pages={{pages}}>
2374
+ * <:link as |link|>
2375
+ * <button {{on "click" (fn features.loadPage link.url)}}>{{link.text}}</button>
2376
+ * </:link>
2377
+ * </EachLink>
2378
+ * ```
2379
+ */
2380
+ loadPage = async (url) => {
2381
+ const cache = this.paginationCache;
2382
+ this._adoptTarget = null;
2383
+ const page = cache.getPageCache(url);
2384
+ this.activePage = page;
2385
+ if (!page.isLoaded || page.isError) {
2386
+ const request = this.store.request(page.isError ? {
2387
+ method: "GET",
2388
+ url,
2389
+ cacheOptions: { reload: true }
2390
+ } : {
2391
+ method: "GET",
2392
+ url
2393
+ });
2394
+ cache.loadPage(url, request);
2395
+ try {
2396
+ await page.request;
2397
+ } catch {
2398
+ return null;
2399
+ }
2400
+ }
2401
+ return page.value;
2402
+ };
2403
+ };
2404
+ defineSignal(PaginationState.prototype, "paginationCache", null);
2405
+ defineSignal(PaginationState.prototype, "activePage", null);
2406
+ defineSignal(PaginationState.prototype, "initialPage", null);
2407
+ defineSignal(PaginationState.prototype, "frontierStart", null);
2408
+ defineSignal(PaginationState.prototype, "frontierEnd", null);
2409
+ const PaginationStateCache = /* @__PURE__ */ new WeakMap();
2410
+ /**
2411
+ * Get the {@link PaginationState} for a given request. Returns the same instance
2412
+ * for the same request future, so that repeated calls (e.g. in a template, or
2413
+ * alongside the `<Paginate />` component using the same request) share the same
2414
+ * local pagination state. Keyed by request identity, just like
2415
+ * {@link getRequestState}.
2416
+ *
2417
+ * ```ts
2418
+ * const future = store.request(query);
2419
+ * const pages = getPaginationState(future);
2420
+ *
2421
+ * await future;
2422
+ * pages.totalPages; // now known, if the response exposed it
2423
+ * await pages.loadNext();
2424
+ * ```
2425
+ *
2426
+ * @since 5.9.0
2427
+ * @public
2428
+ */
2429
+ function getPaginationState(request, pageHints) {
2430
+ let state = PaginationStateCache.get(request);
2431
+ if (!state) {
2432
+ state = new PaginationState(request, pageHints);
2433
+ PaginationStateCache.set(request, state);
2434
+ }
2435
+ return state;
2436
+ }
2437
+
2438
+ //#endregion
2439
+ //#region src/signals/pagination-links.ts
2440
+ const PaginationLinksCache = /* @__PURE__ */ new WeakMap();
2441
+ /**
2442
+ * A single numbered link, e.g. page `3`. Loads its page and makes it active when
2443
+ * {@link setActive} runs. Carries its {@link index} and its
2444
+ * {@link distanceFromActiveIndex} so a UI can style links by how far they sit
2445
+ * from the current page.
2446
+ *
2447
+ * ```gts
2448
+ * <EachLink @pages={{pages}} as |state|>
2449
+ * {{#each state.links as |link|}}
2450
+ * {{#if link.isReal}}
2451
+ * <button class={{if link.isCurrent "active"}} {{on "click" link.setActive}}>
2452
+ * {{link.text}}
2453
+ * </button>
2454
+ * {{/if}}
2455
+ * {{/each}}
2456
+ * </EachLink>
2457
+ * ```
2458
+ *
2459
+ * @since 5.9.0
2460
+ * @public
2461
+ * @hideconstructor
2462
+ */
2463
+ var RealPaginationLink = class {
2464
+ isReal = true;
2465
+ url;
2466
+ index;
2467
+ isCurrent;
2468
+ distanceFromActiveIndex;
2469
+ /** @internal */
2470
+ constructor(url, index, activeIndex, loadPage) {
2471
+ this.url = url;
2472
+ this.index = index;
2473
+ this.isCurrent = index === activeIndex;
2474
+ this.distanceFromActiveIndex = Math.abs(index - activeIndex);
2475
+ this._loadPage = loadPage;
2476
+ }
2477
+ get text() {
2478
+ return `${this.index}`;
2479
+ }
2480
+ /**
2481
+ * Loads this link's page and makes it the active page on the associated
2482
+ * {@link PaginationState}. It is a stable reference, so it is safe to pass
2483
+ * around as an "action" or "event" handler:
2484
+ *
2485
+ * ```gts
2486
+ * <button {{on "click" link.setActive}}>{{link.text}}</button>
2487
+ * ```
2488
+ */
2489
+ setActive = () => {
2490
+ return this._loadPage(this.url);
2491
+ };
2492
+ };
2493
+ /**
2494
+ * A stand-in for a run of pages that have not been loaded yet, rendered as an
2495
+ * ellipsis between numbered links. It covers an {@link indexRange} rather than a
2496
+ * single page and has no page to navigate to.
2497
+ *
2498
+ * ```gts
2499
+ * <EachLink @pages={{pages}} as |state|>
2500
+ * {{#each state.links as |link|}}
2501
+ * {{#unless link.isReal}}
2502
+ * <span title="{{link.rangeSize}} more pages">{{link.text}}</span>
2503
+ * {{/unless}}
2504
+ * {{/each}}
2505
+ * </EachLink>
2506
+ * ```
2507
+ *
2508
+ * @since 5.9.0
2509
+ * @public
2510
+ * @hideconstructor
2511
+ */
2512
+ var PlaceholderPaginationLink = class {
2513
+ isReal = false;
2514
+ /**
2515
+ * The inclusive `[start, end]` page-number range of not-yet-loaded pages this
2516
+ * placeholder stands in for.
2517
+ */
2518
+ indexRange;
2519
+ /** @internal */
2520
+ activeIndex;
2521
+ text = ".";
2522
+ constructor(index, activeIndex) {
2523
+ this.indexRange = index;
2524
+ this.activeIndex = activeIndex;
2525
+ }
2526
+ /** The number of pages this placeholder covers. */
2527
+ get rangeSize() {
2528
+ return this.indexRange[1] - this.indexRange[0] + 1;
2529
+ }
2530
+ /**
2531
+ * The distance between the active page and the nearest edge of this
2532
+ * placeholder's index range.
2533
+ */
2534
+ get distanceFromActiveIndex() {
2535
+ const [start, end] = this.indexRange;
2536
+ return Math.min(Math.abs(start - this.activeIndex), Math.abs(end - this.activeIndex));
2537
+ }
2538
+ /** @internal */
2539
+ _mergeRange(newRange) {
2540
+ const [oldStart, oldEnd] = this.indexRange;
2541
+ const [newStart, newEnd] = newRange;
2542
+ const mergedRange = [Math.min(oldStart, newStart), Math.max(oldEnd, newEnd)];
2543
+ this.indexRange = mergedRange;
2544
+ }
2545
+ };
2546
+ /**
2547
+ * A relational (`first`/`prev`/`next`/`last`) navigation link, relative to the
2548
+ * active page. Unlike {@link RealPaginationLink} these carry no ordinal index —
2549
+ * they are the only links available for cursor-based pagination, where pages are
2550
+ * chained purely by opaque relational links with no page number or total. They
2551
+ * are also available in numbered pagination as a convenience.
2552
+ *
2553
+ * ```gts
2554
+ * <EachLink @pages={{pages}} as |state|>
2555
+ * {{#if state.prev}}<button {{on "click" state.prev.setActive}}>Previous</button>{{/if}}
2556
+ * {{#if state.next}}<button {{on "click" state.next.setActive}}>Next</button>{{/if}}
2557
+ * </EachLink>
2558
+ * ```
2559
+ *
2560
+ * @since 5.9.0
2561
+ * @public
2562
+ * @hideconstructor
2563
+ */
2564
+ var RelationalPaginationLink = class {
2565
+ isReal = true;
2566
+ rel;
2567
+ url;
2568
+ /**
2569
+ * Whether this link points at the page that is already active — for example
2570
+ * the `first` link while the first page is being viewed. Useful for
2571
+ * disabling the control.
2572
+ */
2573
+ isCurrent;
2574
+ /** @internal */
2575
+ constructor(rel, url, isCurrent, loadPage) {
2576
+ this.rel = rel;
2577
+ this.url = url;
2578
+ this.isCurrent = isCurrent;
2579
+ this._loadPage = loadPage;
2580
+ }
2581
+ get text() {
2582
+ return this.rel;
2583
+ }
2584
+ /**
2585
+ * Loads this link's page and makes it the active page on the associated
2586
+ * {@link PaginationState}. It is a stable reference, so it is safe to pass
2587
+ * around as an "action" or "event" handler:
2588
+ *
2589
+ * ```gts
2590
+ * <button {{on "click" link.setActive}}>{{link.text}}</button>
2591
+ * ```
2592
+ */
2593
+ setActive = () => {
2594
+ return this._loadPage(this.url);
2595
+ };
2596
+ };
2597
+ /**
2598
+ * A member of {@link PaginationLinks.links}: either a numbered
2599
+ * {@link RealPaginationLink} or a {@link PlaceholderPaginationLink} standing in
2600
+ * for a gap. Discriminate with {@link RealPaginationLink.isReal | isReal}:
2601
+ *
2602
+ * ```ts
2603
+ * for (const link of links.links) {
2604
+ * if (link.isReal) {
2605
+ * // numbered link: link.index, link.setActive
2606
+ * } else {
2607
+ * // gap: link.indexRange
2608
+ * }
2609
+ * }
2610
+ * ```
2611
+ */
2612
+ /**
2613
+ * The reactive set of navigation links derived from a {@link PaginationState}.
2614
+ * Where `PaginationState` tracks which pages are loaded and which one is active,
2615
+ * `PaginationLinks` turns that page graph into the links a UI renders to move
2616
+ * between pages.
2617
+ *
2618
+ * It provides two kinds of link:
2619
+ *
2620
+ * - {@link links}: the numbered links, with {@link PlaceholderPaginationLink}
2621
+ * placeholders standing in for gaps of not-yet-loaded pages. Only numbered
2622
+ * collections (where the server exposes page numbers) produce these.
2623
+ * - {@link prev} and {@link next}: the relational links for the active page.
2624
+ * Available in both numbered and cursor-based pagination, and the only links a
2625
+ * cursor-based collection has.
2626
+ * - {@link first} and {@link last}: the relational links to the collection's
2627
+ * edges, when the response exposes them. Usually present on every page —
2628
+ * including the edge page itself, where the link's
2629
+ * {@link RelationalPaginationLink.isCurrent | isCurrent} is `true`.
2630
+ *
2631
+ * Every link updates as pages load and as the active page changes, since they
2632
+ * read straight from the state's shared page graph. To get the links for a
2633
+ * state, use {@link getPaginationLinks}.
2634
+ *
2635
+ * See also:
2636
+ * - {@link RealPaginationLink}
2637
+ * - {@link PlaceholderPaginationLink}
2638
+ * - {@link RelationalPaginationLink}
2639
+ *
2640
+ * @since 5.9.0
2641
+ * @public
2642
+ * @hideconstructor
2643
+ */
2644
+ var PaginationLinks = class {
2645
+ /** @internal */
2646
+ constructor(paginationState) {
2647
+ this.paginationState = paginationState;
2648
+ }
2649
+ /**
2650
+ * The relational `first` link of the collection, or `null` when the active
2651
+ * page's response did not expose one. Unlike {@link prev}/{@link next} it is
2652
+ * usually present on every page — including the first page itself, where the
2653
+ * link's {@link RelationalPaginationLink.isCurrent | isCurrent} is `true`
2654
+ * (useful for disabling the control).
2655
+ */
2656
+ get first() {
2657
+ const activePage = this.paginationState.activePage;
2658
+ const url = activePage?.firstLink;
2659
+ return url ? new RelationalPaginationLink("first", url, url === activePage?.selfLink, this.paginationState.loadPage) : null;
2660
+ }
2661
+ /**
2662
+ * The relational `prev` link for the active page, or `null` at the start of the
2663
+ * collection. Available in both numbered and cursor pagination.
2664
+ */
2665
+ static {
2666
+ decorateMethodV2(this.prototype, "first", [memoized]);
2667
+ }
2668
+ get prev() {
2669
+ const activePage = this.paginationState.activePage;
2670
+ const url = activePage?.prevLink;
2671
+ return url ? new RelationalPaginationLink("prev", url, url === activePage?.selfLink, this.paginationState.loadPage) : null;
2672
+ }
2673
+ /**
2674
+ * The relational `next` link for the active page, or `null` at the end of the
2675
+ * collection. Available in both numbered and cursor pagination.
2676
+ */
2677
+ static {
2678
+ decorateMethodV2(this.prototype, "prev", [memoized]);
2679
+ }
2680
+ get next() {
2681
+ const activePage = this.paginationState.activePage;
2682
+ const url = activePage?.nextLink;
2683
+ return url ? new RelationalPaginationLink("next", url, url === activePage?.selfLink, this.paginationState.loadPage) : null;
2684
+ }
2685
+ /**
2686
+ * The relational `last` link of the collection, or `null` when the active
2687
+ * page's response did not expose one. Mirror of {@link first} for the end of
2688
+ * the collection.
2689
+ */
2690
+ static {
2691
+ decorateMethodV2(this.prototype, "next", [memoized]);
2692
+ }
2693
+ get last() {
2694
+ const activePage = this.paginationState.activePage;
2695
+ const url = activePage?.lastLink;
2696
+ return url ? new RelationalPaginationLink("last", url, url === activePage?.selfLink, this.paginationState.loadPage) : null;
2697
+ }
2698
+ /**
2699
+ * The numbered links and placeholders, derived from the shared page graph.
2700
+ *
2701
+ * Only produced for numbered pagination (where the server exposes page numbers).
2702
+ * Cursor-based collections have no page numbers, so this is empty — use
2703
+ * {@link prev}/{@link next} for cursor navigation.
2704
+ */
2705
+ static {
2706
+ decorateMethodV2(this.prototype, "last", [memoized]);
2707
+ }
2708
+ get links() {
2709
+ const links = [];
2710
+ const cache = this.paginationState.paginationCache;
2711
+ if (!cache || !cache.isNumbered) return links;
2712
+ const { firstPage, totalPages } = cache;
2713
+ const activeIndex = this.paginationState.activePage?.pageNumber ?? 0;
2714
+ if (firstPage) {
2715
+ let previousPage = null;
2716
+ let currentPage = firstPage;
2717
+ while (currentPage) {
2718
+ if (previousPage && currentPage.pageNumber - previousPage.pageNumber > 1) links.push(new PlaceholderPaginationLink([previousPage.pageNumber + 1, currentPage.pageNumber - 1], activeIndex));
2719
+ links.push(new RealPaginationLink(currentPage.selfLink ?? "", currentPage.pageNumber, activeIndex, this.paginationState.loadPage));
2720
+ previousPage = currentPage;
2721
+ currentPage = currentPage.after;
2722
+ }
2723
+ if (previousPage && previousPage.pageNumber < totalPages) links.push(new PlaceholderPaginationLink([previousPage.pageNumber + 1, totalPages], activeIndex));
2724
+ }
2725
+ return links;
2726
+ }
2727
+ static {
2728
+ decorateMethodV2(this.prototype, "links", [memoized]);
2729
+ }
2730
+ };
2731
+ /**
2732
+ * Get the {@link PaginationLinks} for a given {@link PaginationState}. Returns
2733
+ * the same instance for the same state, so repeated calls (for example a
2734
+ * `<Paginate />` component and a separate links component reading the same state)
2735
+ * share one set of links. Keyed by state identity, the same way
2736
+ * {@link getPaginationState} is keyed by request and {@link getRequestState} by
2737
+ * future.
2738
+ *
2739
+ * ```ts
2740
+ * const links = getPaginationLinks(paginationState);
2741
+ *
2742
+ * for (const link of links.links) {
2743
+ * if (link.isReal) {
2744
+ * // render a numbered link, using link.setActive as the click handler
2745
+ * } else {
2746
+ * // render an ellipsis for the gap link.indexRange covers
2747
+ * }
2748
+ * }
2749
+ * ```
2750
+ *
2751
+ * @since 5.9.0
2752
+ * @public
2753
+ */
2754
+ function getPaginationLinks(state) {
2755
+ let links = PaginationLinksCache.get(state);
2756
+ if (!links) {
2757
+ links = new PaginationLinks(state);
2758
+ PaginationLinksCache.set(state, links);
2759
+ }
2760
+ return links;
2761
+ }
2762
+
2763
+ //#endregion
2764
+ //#region src/signals/pagination-subscription.ts
2765
+ /**
2766
+ * The content features available in both pagination modes: the state and
2767
+ * controls of the initial request.
2768
+ */
2769
+ /**
2770
+ * The content features yielded in `'paged'` mode: navigation happens by
2771
+ * loading a specific page.
2772
+ */
2773
+ /**
2774
+ * The content features yielded in `'infinite'` mode: navigation happens by
2775
+ * extending the loaded run at either end.
2776
+ */
2777
+ /**
2778
+ * The full set of content features a {@link PaginationSubscription} builds —
2779
+ * both modes' surfaces. The `<Paginate />` component narrows this to one mode
2780
+ * via {@link PaginationContentFeaturesFor} before yielding.
2781
+ */
2782
+ /**
2783
+ * Resolves a {@link PaginateMode} to the content features it exposes. Mirror of
2784
+ * {@link PaginationStateFor}.
2785
+ */
2786
+ /**
2787
+ * Lifecycle glue for the `<Paginate />` component. Owns the initial
2788
+ * {@link RequestSubscription} (loading/error state, autorefresh, disposal) and
2789
+ * the per-component {@link PaginationState} that it hands to the component.
2790
+ *
2791
+ * @since 5.9.0
2792
+ * @public
2793
+ * @hideconstructor
2794
+ */
2795
+ var PaginationSubscription = class {
2796
+ /** @internal */
2797
+ /** @internal */
2798
+ /** @internal */
2799
+ /**
2800
+ * The Store this subscription subscribes to or the RequestManager
2801
+ * which issues this request.
2802
+ */
2803
+ /**
2804
+ * The wrapped {@link RequestSubscription} monitoring the initial request.
2805
+ * Created eagerly: constructing one consumes reactive state (its own
2806
+ * signals), so building it lazily inside a tracked getter would cause the
2807
+ * getter to invalidate — and the subscription to be recreated, losing its
2808
+ * reloaded request — whenever `retry`/`reload` runs.
2809
+ *
2810
+ * @internal
2811
+ */
2812
+ /**
2813
+ * The first request this subscription saw — the one that keys the
2814
+ * {@link PaginationState} until a navigation resolves to a different
2815
+ * collection. Plain (untracked) because it is written during the first
2816
+ * computation of {@link paginationState}.
2817
+ *
2818
+ * @internal
2819
+ */
2820
+ /**
2821
+ * The request a resolved navigation swapped the {@link PaginationState} to,
2822
+ * when the navigation turned out to target a different collection. A signal:
2823
+ * writing it (always outside of render, from {@link _resolveNavigation})
2824
+ * invalidates {@link paginationState} so the fresh state takes over.
2825
+ *
2826
+ * @internal
2827
+ */
2828
+ /**
2829
+ * The changed request currently being resolved by {@link _resolveNavigation},
2830
+ * both to avoid kicking the same navigation twice and as the latest-wins
2831
+ * guard when several changes race. Untracked bookkeeping.
2832
+ *
2833
+ * @internal
2834
+ */
2835
+ constructor(store, args) {
2836
+ this._args = args;
2837
+ this.store = store;
2838
+ this.isDestroyed = false;
2839
+ this._seedRequest = null;
2840
+ this._navTarget = null;
2841
+ this[DISPOSE] = _DISPOSE$1;
2842
+ this._requestSubscription = createRequestSubscription(store, args);
2843
+ }
2844
+ /**
2845
+ * The per-component pagination state yielded to the component.
2846
+ *
2847
+ * Keyed to the request that started the collection, not the current
2848
+ * `@request` arg: when the arg changes, the existing state keeps rendering
2849
+ * while {@link _resolveNavigation} resolves the new request in the
2850
+ * background. A request that resolves to a page of the same collection is
2851
+ * adopted into this state as the new active page (route-driven navigation,
2852
+ * e.g. the browser back button); one that resolves to a different
2853
+ * collection swaps in a fresh state (a true reset).
2854
+ *
2855
+ * A background `refresh` does not swap the request, so the pagination
2856
+ * state is stable across refreshes.
2857
+ */
2858
+ get paginationState() {
2859
+ const request = this._requestSubscription.request;
2860
+ const active = this._navRequest ?? this._seedRequest;
2861
+ if (!active) {
2862
+ this._seedRequest = request;
2863
+ return getPaginationState(request, this._args.pageHints);
2864
+ }
2865
+ if (request !== active && request !== this._navTarget) {
2866
+ this._navTarget = request;
2867
+ this._resolveNavigation(request);
2868
+ }
2869
+ return getPaginationState(active, this._args.pageHints);
2870
+ }
2871
+ /**
2872
+ * Resolves a changed `@request` arg against the current collection via
2873
+ * {@link PaginationState.adoptPage}: a request that resolves to a page of
2874
+ * the same collection is adopted into the existing state; one that resolves
2875
+ * to a different collection (or arrives before a collection is loaded) swaps
2876
+ * the state for a fresh one keyed to this request.
2877
+ *
2878
+ * A rejected request changes nothing here — the request subscription
2879
+ * already surfaces the failure (error/cancelled states), and the existing
2880
+ * pagination state is kept for recovery. The request is awaited before
2881
+ * `adoptPage` so that rejection and the latest-wins guard are handled
2882
+ * before anything is adopted.
2883
+ *
2884
+ * @internal
2885
+ */
2886
+ static {
2887
+ decorateMethodV2(this.prototype, "paginationState", [memoized]);
2888
+ }
2889
+ async _resolveNavigation(request) {
2890
+ try {
2891
+ await request;
2892
+ } catch {
2893
+ return;
2894
+ }
2895
+ if (this.isDestroyed || this._navTarget !== request) return;
2896
+ const adopted = await this.paginationState.adoptPage(request);
2897
+ if (this.isDestroyed || this._navTarget !== request) return;
2898
+ if (adopted === null) this._navRequest = request;
2899
+ }
2900
+ /**
2901
+ * Whether there is no request or query to monitor, so the component has
2902
+ * nothing to load.
2903
+ */
2904
+ get isIdle() {
2905
+ return this._requestSubscription.isIdle;
2906
+ }
2907
+ /**
2908
+ * Whether the collection is still blocking-loading: no {@link PaginationState}
2909
+ * has finished setting up yet. Only the very first page load (or the reset
2910
+ * to a different collection) blocks here — extending the collection with
2911
+ * `loadNext`/`loadPrev` does not, and neither does a changed `@request` arg
2912
+ * while a collection is already on screen (that is {@link isNavigating}).
2913
+ *
2914
+ * Remains `true` for the moment between the request resolving and the
2915
+ * {@link paginationState} finishing its setup from the response, so that
2916
+ * {@link isSuccess} consumers never see a success state with an empty
2917
+ * pagination surface.
2918
+ */
2919
+ static {
2920
+ decorateMethodV2(this.prototype, "isIdle", [memoized]);
2921
+ }
2922
+ get isLoading() {
2923
+ const { reqState } = this._requestSubscription;
2924
+ return this.paginationState.paginationCache === null && (reqState.isLoading || reqState.isSuccess);
2925
+ }
2926
+ /**
2927
+ * Whether a changed `@request` arg is resolving while a collection is
2928
+ * already on screen — route-driven navigation, e.g. the browser back
2929
+ * button. The content stays rendered (see {@link isSuccess}); consumers can
2930
+ * use this to show a lightweight navigation indicator, the same way a
2931
+ * `loadPage` call surfaces through the active page's request state.
2932
+ */
2933
+ static {
2934
+ decorateMethodV2(this.prototype, "isLoading", [memoized]);
2935
+ }
2936
+ get isNavigating() {
2937
+ return this.paginationState.paginationCache !== null && this._requestSubscription.reqState.isLoading;
2938
+ }
2939
+ /**
2940
+ * The {@link RequestLoadingState} for the initial request, for building UIs
2941
+ * that respond to download progress.
2942
+ */
2943
+ static {
2944
+ decorateMethodV2(this.prototype, "isNavigating", [memoized]);
2945
+ }
2946
+ get loadingState() {
2947
+ return this._requestSubscription.reqState.loadingState;
2948
+ }
2949
+ /**
2950
+ * Whether the component has a set-up {@link paginationState} to render and
2951
+ * the current request did not fail. Stays `true` while a changed `@request`
2952
+ * arg resolves ({@link isNavigating}), so the existing content keeps
2953
+ * rendering instead of falling back to a blocking loading state.
2954
+ */
2955
+ static {
2956
+ decorateMethodV2(this.prototype, "loadingState", [memoized]);
2957
+ }
2958
+ get isSuccess() {
2959
+ const { reqState } = this._requestSubscription;
2960
+ return this.paginationState.paginationCache !== null && !reqState.isError && !reqState.isCancelled;
2961
+ }
2962
+ /**
2963
+ * Whether the initial request was cancelled (aborted).
2964
+ */
2965
+ static {
2966
+ decorateMethodV2(this.prototype, "isSuccess", [memoized]);
2967
+ }
2968
+ get isCancelled() {
2969
+ return this._requestSubscription.reqState.isCancelled;
2970
+ }
2971
+ /**
2972
+ * Whether the initial request rejected with an error.
2973
+ */
2974
+ static {
2975
+ decorateMethodV2(this.prototype, "isCancelled", [memoized]);
2976
+ }
2977
+ get isError() {
2978
+ return this._requestSubscription.reqState.isError;
2979
+ }
2980
+ /**
2981
+ * The error the initial request rejected with, or `null` if it did not reject.
2982
+ */
2983
+ static {
2984
+ decorateMethodV2(this.prototype, "isError", [memoized]);
2985
+ }
2986
+ get reason() {
2987
+ return this._requestSubscription.reqState.reason;
2988
+ }
2989
+ /**
2990
+ * Error features to yield to the error slot of a component
2991
+ */
2992
+ static {
2993
+ decorateMethodV2(this.prototype, "reason", [memoized]);
2994
+ }
2995
+ get errorFeatures() {
2996
+ return {
2997
+ isHidden: this._requestSubscription.isHidden,
2998
+ isOnline: this._requestSubscription.isOnline,
2999
+ retry: this._requestSubscription.retry
3000
+ };
3001
+ }
3002
+ /**
3003
+ * Content features to yield to the content slot of a component
3004
+ */
3005
+ static {
3006
+ decorateMethodV2(this.prototype, "errorFeatures", [memoized]);
3007
+ }
3008
+ get contentFeatures() {
3009
+ const contentFeatures = this._requestSubscription.contentFeatures;
3010
+ const { paginationState } = this;
3011
+ const feat = {
3012
+ ...contentFeatures,
3013
+ isNavigating: this.isNavigating,
3014
+ loadPrev: paginationState.loadPrev,
3015
+ loadNext: paginationState.loadNext,
3016
+ loadPage: paginationState.loadPage
3017
+ };
3018
+ if (feat.isRefreshing) feat.abort = () => {
3019
+ contentFeatures.latestRequest?.abort();
3020
+ };
3021
+ return feat;
3022
+ }
3023
+ /**
3024
+ * The initial request `Future` this subscription is monitoring, i.e. the first
3025
+ * page load. This is the future the {@link paginationState} is built from.
3026
+ *
3027
+ * @internal
3028
+ */
3029
+ static {
3030
+ decorateMethodV2(this.prototype, "contentFeatures", [memoized]);
3031
+ }
3032
+ get request() {
3033
+ return this._requestSubscription.request;
3034
+ }
3035
+ static {
3036
+ decorateMethodV2(this.prototype, "request", [memoized]);
3037
+ }
3038
+ };
3039
+ defineSignal(PaginationSubscription.prototype, "_navRequest", null);
3040
+ /**
3041
+ * Creates the {@link PaginationSubscription} a `<Paginate />` component uses to
3042
+ * manage its request lifecycle and pagination state. Pass the result back into
3043
+ * the component via `@subscription` to manage the lifecycle externally.
3044
+ *
3045
+ * ```ts
3046
+ * const subscription = createPaginationSubscription(store, { request });
3047
+ *
3048
+ * subscription.paginationState; // the per-component PaginationState
3049
+ * subscription[DISPOSE](); // tear down when the owning component unmounts
3050
+ * ```
3051
+ *
3052
+ * @since 5.9.0
3053
+ * @public
3054
+ */
3055
+ function createPaginationSubscription(store, args) {
3056
+ return new PaginationSubscription(store, args);
3057
+ }
3058
+ function upgradeSubscription$1(sub) {
3059
+ return sub;
3060
+ }
3061
+ function _DISPOSE$1() {
3062
+ const self = upgradeSubscription$1(this);
3063
+ self.isDestroyed = true;
3064
+ self._requestSubscription?.[DISPOSE]?.();
3065
+ }
3066
+
3067
+ //#endregion
3068
+ //#region src/signals/pagination-links-subscription.ts
3069
+ /**
3070
+ * The framework-agnostic core of a pagination links component (for example the
3071
+ * `<EachLink />` component of `@warp-drive/ember`): it owns the component
3072
+ * lifecycle, while the links themselves live on the {@link PaginationLinks}
3073
+ * it exposes.
3074
+ *
3075
+ * Given the {@link PagedPaginationState} a `<Paginate />` component is driving,
3076
+ * {@link paginationLinks} derives that state's `PaginationLinks` — the numbered
3077
+ * links (with placeholders for gaps) and the relational
3078
+ * `first`/`prev`/`next`/`last` links a component yields for the consumer to
3079
+ * render. All of them read from the same shared page graph as the
3080
+ * `<Paginate />` component, so they stay in sync as pages load and the active
3081
+ * page changes.
3082
+ *
3083
+ * @since 5.9.0
3084
+ * @public
3085
+ * @hideconstructor
3086
+ */
3087
+ var PaginationLinksSubscription = class {
3088
+ /** @internal */
3089
+ /** @internal */
3090
+ constructor(args) {
3091
+ this._args = args;
3092
+ this.isDestroyed = false;
3093
+ this[DISPOSE] = _DISPOSE;
3094
+ }
3095
+ /**
3096
+ * The {@link PaginationLinks} derived from the {@link PagedPaginationState}
3097
+ * passed as an arg — the surface a links component yields to its consumer:
3098
+ * the numbered {@link PaginationLinks.links | links} (empty for cursor-based
3099
+ * collections) and the relational {@link PaginationLinks.first | first}/
3100
+ * {@link PaginationLinks.prev | prev}/{@link PaginationLinks.next | next}/
3101
+ * {@link PaginationLinks.last | last} links.
3102
+ *
3103
+ * Recomputes when the `pages` arg changes, so a component whose pagination
3104
+ * resets to a different collection derives fresh links automatically.
3105
+ */
3106
+ get paginationLinks() {
3107
+ return getPaginationLinks(this._args.pages);
3108
+ }
3109
+ static {
3110
+ decorateMethodV2(this.prototype, "paginationLinks", [memoized]);
3111
+ }
3112
+ };
3113
+ /**
3114
+ * Creates the {@link PaginationLinksSubscription} a links component (such as
3115
+ * `<EachLink />`) uses to derive its links from a {@link PagedPaginationState}.
3116
+ *
3117
+ * ```ts
3118
+ * const subscription = createPaginationLinksSubscription({ pages: paginationState });
3119
+ *
3120
+ * subscription.paginationLinks; // the derived PaginationLinks
3121
+ * subscription[DISPOSE](); // tear down when the owning component unmounts
3122
+ * ```
3123
+ *
3124
+ * @since 5.9.0
3125
+ * @public
3126
+ */
3127
+ function createPaginationLinksSubscription(args) {
3128
+ return new PaginationLinksSubscription(args);
3129
+ }
3130
+ function upgradeSubscription(sub) {
3131
+ return sub;
3132
+ }
3133
+ function _DISPOSE() {
3134
+ const self = upgradeSubscription(this);
3135
+ self.isDestroyed = true;
3136
+ }
3137
+
3138
+ //#endregion
3139
+ //#region src/signals/promise-state.ts
3140
+ const PromiseCache = /* @__PURE__ */ new WeakMap();
3141
+ /**
3142
+ * The state of a promise in the "pending"
3143
+ * state. This is the default initial state.
3144
+ *
3145
+ */
3146
+ /**
3147
+ * The state of a promise in the "fulfilled" state.
3148
+ * This is the state of a promise that has resolved
3149
+ * successfully.
3150
+ *
3151
+ */
3152
+ /**
3153
+ * The state of a promise in the "rejected" state.
3154
+ * This is the state of a promise that has rejected
3155
+ * with an error.
3156
+ *
3157
+ */
3158
+ /**
3159
+ * The state of a promise. This is the type that is returned
3160
+ * from `getPromiseState`.
3161
+ *
3162
+ * See also:
3163
+ * - {@link PendingPromise}
3164
+ * - {@link ResolvedPromise}
3165
+ * - {@link RejectedPromise}
3166
+ *
3167
+ */
3168
+ const PromiseStateProto = {};
3169
+ defineSignal(PromiseStateProto, "reason", null);
3170
+ defineSignal(PromiseStateProto, "value", null);
3171
+ defineSignal(PromiseStateProto, "result", null);
3172
+ defineSignal(PromiseStateProto, "error", null);
3173
+ defineSignal(PromiseStateProto, "status", "pending");
3174
+ defineSignal(PromiseStateProto, "isPending", true);
3175
+ defineSignal(PromiseStateProto, "isLoading", true);
3176
+ defineSignal(PromiseStateProto, "isSuccess", false);
3177
+ defineSignal(PromiseStateProto, "isError", false);
3178
+ function createPromiseState(promise) {
3179
+ const state = getPromiseResult(promise);
3180
+ const promiseState = Object.create(PromiseStateProto);
3181
+ if (state) {
3182
+ if (state.isError) {
3183
+ promiseState.error = state.result;
3184
+ promiseState.reason = state.result;
3185
+ promiseState.status = "rejected";
3186
+ promiseState.isError = true;
3187
+ promiseState.isPending = false;
3188
+ promiseState.isLoading = false;
3189
+ } else {
3190
+ promiseState.result = state.result;
3191
+ promiseState.value = state.result;
3192
+ promiseState.status = "fulfilled";
3193
+ promiseState.isSuccess = true;
3194
+ promiseState.isPending = false;
3195
+ promiseState.isLoading = false;
3196
+ }
3197
+ } else promise.then((result) => {
3198
+ setPromiseResult(promise, {
3199
+ isError: false,
3200
+ result
3201
+ });
3202
+ promiseState.result = result;
3203
+ promiseState.value = result;
3204
+ promiseState.status = "fulfilled";
3205
+ promiseState.isSuccess = true;
3206
+ promiseState.isPending = false;
3207
+ promiseState.isLoading = false;
3208
+ }, (error) => {
3209
+ setPromiseResult(promise, {
3210
+ isError: true,
3211
+ result: error
3212
+ });
3213
+ promiseState.error = error;
3214
+ promiseState.reason = error;
3215
+ promiseState.status = "rejected";
3216
+ promiseState.isError = true;
3217
+ promiseState.isPending = false;
3218
+ promiseState.isLoading = false;
3219
+ });
3220
+ return promiseState;
3221
+ }
3222
+ const LegacyPromiseProxy = Symbol.for("LegacyPromiseProxy");
3223
+ function isLegacyAwaitable(promise) {
3224
+ return LegacyPromiseProxy in promise && "promise" in promise && promise[LegacyPromiseProxy] === true;
3225
+ }
3226
+ function getPromise(promise) {
3227
+ return isLegacyAwaitable(promise) ? promise.promise : promise;
3228
+ }
3229
+ /**
3230
+ * Returns a reactive state-machine for the provided promise or awaitable.
3231
+ *
3232
+ * Repeat calls to `getPromiseState` with the same promise will return the same state object
3233
+ * making is safe and easy to use in templates and JavaScript code to produce reactive
3234
+ * behaviors around promises.
3235
+ *
3236
+ * `getPromiseState` can be used in both JavaScript and Template contexts.
3237
+ *
3238
+ * ```ts
3239
+ * import { getPromiseState } from '@warp-drive/ember';
3240
+ *
3241
+ * const state = getPromiseState(promise);
3242
+ * ```
3243
+ *
3244
+ * For instance, we could write a getter on a component that updates whenever
3245
+ * the promise state advances or the promise changes, by combining the function
3246
+ * with the use of `@cached`
3247
+ *
3248
+ * ```ts
3249
+ * class Component {
3250
+ * @cached
3251
+ * get title() {
3252
+ * const state = getPromiseState(this.args.request);
3253
+ * if (state.isPending) {
3254
+ * return 'loading...';
3255
+ * }
3256
+ * if (state.isError) { return null; }
3257
+ * return state.result.title;
3258
+ * }
3259
+ * }
3260
+ * ```
3261
+ *
3262
+ * Or in a template as a helper:
3263
+ *
3264
+ * ```gjs
3265
+ * import { getPromiseState } from '@warp-drive/ember';
3266
+ *
3267
+ * <template>
3268
+ * {{#let (getPromiseState @request) as |state|}}
3269
+ * {{#if state.isPending}} <Spinner />
3270
+ * {{else if state.isError}} <ErrorForm @error={{state.error}} />
3271
+ * {{else}}
3272
+ * <h1>{{state.result.title}}</h1>
3273
+ * {{/if}}
3274
+ * {{/let}}
3275
+ * </template>
3276
+ * ```
3277
+ *
3278
+ * If looking to use in a template, consider also the `<Await />` component.
3279
+ *
3280
+ * See also {@link PromiseState}
3281
+ */
3282
+ function getPromiseState(promise) {
3283
+ const _promise = getPromise(promise);
3284
+ let state = PromiseCache.get(_promise);
3285
+ if (!state) {
3286
+ state = createPromiseState(_promise);
3287
+ PromiseCache.set(_promise, state);
3288
+ }
3289
+ return state;
3290
+ }
3291
+
3292
+ //#endregion
3293
+ export { ARRAY_SIGNAL as A, createInternalMemo as C, notifyInternalSignal as D, makeInitializer as E, setupSignals as M, waitFor as N, peekInternalSignal as O, willSyncFlushWatchers as P, consumeInternalSignal as S, getOrCreateInternalSignal as T, entangleSignal as _, getPaginationState as a, signal as b, getPaginationCache as c, getRequestState as d, createSignalDescriptor as f, entangleInitiallyStaleSignal as g, defineSignal as h, getPaginationLinks as i, OBJECT_SIGNAL as j, withSignalStore as k, DISPOSE as l, defineNonEnumerableSignal as m, createPaginationLinksSubscription as n, clearPaginationCache as o, defineGate as p, createPaginationSubscription as r, defaultPageHints as s, getPromiseState as t, createRequestSubscription as u, gate as v, createInternalSignal as w, Signals as x, memoized as y };
3294
+ //# sourceMappingURL=-private-ggVX_Iob.js.map