ripple 0.3.12 → 0.3.14

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 (217) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/package.json +11 -30
  3. package/src/compiler/types/import.d.ts +0 -12
  4. package/src/helpers.d.ts +2 -0
  5. package/src/runtime/array.js +38 -38
  6. package/src/runtime/create-subscriber.js +2 -2
  7. package/src/runtime/index-client.js +15 -13
  8. package/src/runtime/index-server.js +18 -11
  9. package/src/runtime/internal/client/bindings.js +4 -6
  10. package/src/runtime/internal/client/blocks.js +19 -23
  11. package/src/runtime/internal/client/constants.js +20 -9
  12. package/src/runtime/internal/client/events.js +8 -3
  13. package/src/runtime/internal/client/hmr.js +5 -17
  14. package/src/runtime/internal/client/index.js +14 -4
  15. package/src/runtime/internal/client/runtime.js +436 -173
  16. package/src/runtime/internal/client/try.js +334 -156
  17. package/src/runtime/internal/client/types.d.ts +26 -0
  18. package/src/runtime/internal/server/blocks.js +181 -0
  19. package/src/runtime/internal/server/constants.js +7 -0
  20. package/src/runtime/internal/server/index.js +774 -150
  21. package/src/runtime/internal/server/types.d.ts +35 -0
  22. package/src/runtime/media-query.js +34 -33
  23. package/src/runtime/object.js +7 -10
  24. package/src/runtime/proxy.js +2 -3
  25. package/src/runtime/reactive-value.js +23 -21
  26. package/src/server/index.js +1 -1
  27. package/src/utils/ast.js +1 -1
  28. package/src/utils/async.js +35 -0
  29. package/src/utils/attributes.js +43 -0
  30. package/src/utils/builders.js +5 -3
  31. package/tests/client/__snapshots__/computed-properties.test.rsrx.snap +49 -0
  32. package/tests/client/__snapshots__/for.test.rsrx.snap +319 -0
  33. package/tests/client/__snapshots__/html.test.rsrx.snap +40 -0
  34. package/tests/client/_etc.test.rsrx +7 -0
  35. package/tests/client/array/{array.static.test.ripple → array.static.test.rsrx} +18 -20
  36. package/tests/client/async-suspend.test.rsrx +662 -0
  37. package/tests/client/basic/__snapshots__/basic.attributes.test.rsrx.snap +60 -0
  38. package/tests/client/basic/__snapshots__/basic.rendering.test.rsrx.snap +59 -0
  39. package/tests/client/basic/{basic.errors.test.ripple → basic.errors.test.rsrx} +3 -3
  40. package/tests/client/basic/{basic.styling.test.ripple → basic.styling.test.rsrx} +1 -1
  41. package/tests/client/compiler/__snapshots__/compiler.assignments.test.rsrx.snap +12 -0
  42. package/tests/client/compiler/__snapshots__/compiler.typescript.test.rsrx.snap +46 -0
  43. package/tests/client/compiler/{compiler.assignments.test.ripple → compiler.assignments.test.rsrx} +1 -1
  44. package/tests/client/compiler/{compiler.attributes.test.ripple → compiler.attributes.test.rsrx} +1 -1
  45. package/tests/client/compiler/{compiler.basic.test.ripple → compiler.basic.test.rsrx} +13 -13
  46. package/tests/client/compiler/{compiler.tracked-access.test.ripple → compiler.tracked-access.test.rsrx} +1 -1
  47. package/tests/client/compiler/{compiler.try-in-function.test.ripple → compiler.try-in-function.test.rsrx} +9 -7
  48. package/tests/client/compiler/{compiler.typescript.test.ripple → compiler.typescript.test.rsrx} +1 -1
  49. package/tests/client/composite/__snapshots__/composite.render.test.rsrx.snap +37 -0
  50. package/tests/client/css/{global-additional-cases.test.ripple → global-additional-cases.test.rsrx} +1 -1
  51. package/tests/client/css/{global-advanced-selectors.test.ripple → global-advanced-selectors.test.rsrx} +1 -1
  52. package/tests/client/css/{global-at-rules.test.ripple → global-at-rules.test.rsrx} +1 -1
  53. package/tests/client/css/{global-basic.test.ripple → global-basic.test.rsrx} +1 -1
  54. package/tests/client/css/{global-classes-ids.test.ripple → global-classes-ids.test.rsrx} +1 -1
  55. package/tests/client/css/{global-combinators.test.ripple → global-combinators.test.rsrx} +1 -1
  56. package/tests/client/css/{global-complex-nesting.test.ripple → global-complex-nesting.test.rsrx} +1 -1
  57. package/tests/client/css/{global-edge-cases.test.ripple → global-edge-cases.test.rsrx} +1 -1
  58. package/tests/client/css/{global-keyframes.test.ripple → global-keyframes.test.rsrx} +1 -1
  59. package/tests/client/css/{global-nested.test.ripple → global-nested.test.rsrx} +1 -1
  60. package/tests/client/css/{global-pseudo.test.ripple → global-pseudo.test.rsrx} +1 -1
  61. package/tests/client/css/{global-scoping.test.ripple → global-scoping.test.rsrx} +1 -1
  62. package/tests/client/css/{style-identifier.test.ripple → style-identifier.test.rsrx} +1 -1
  63. package/tests/client/{function-overload.test.ripple → function-overload.test.rsrx} +1 -1
  64. package/tests/client/{return.test.ripple → return.test.rsrx} +1 -1
  65. package/tests/client/try.test.rsrx +1702 -0
  66. package/tests/hydration/build-components.js +6 -4
  67. package/tests/hydration/compiled/client/head.js +11 -11
  68. package/tests/hydration/compiled/client/mixed-control-flow.js +55 -70
  69. package/tests/hydration/compiled/client/nested-control-flow.js +72 -88
  70. package/tests/hydration/compiled/client/try.js +42 -54
  71. package/tests/hydration/compiled/server/basic.js +491 -369
  72. package/tests/hydration/compiled/server/composite.js +153 -128
  73. package/tests/hydration/compiled/server/events.js +166 -145
  74. package/tests/hydration/compiled/server/for.js +821 -677
  75. package/tests/hydration/compiled/server/head.js +200 -165
  76. package/tests/hydration/compiled/server/hmr.js +62 -54
  77. package/tests/hydration/compiled/server/html-in-template.js +64 -55
  78. package/tests/hydration/compiled/server/html.js +1477 -1360
  79. package/tests/hydration/compiled/server/if-children.js +448 -408
  80. package/tests/hydration/compiled/server/if.js +204 -171
  81. package/tests/hydration/compiled/server/mixed-control-flow.js +237 -195
  82. package/tests/hydration/compiled/server/nested-control-flow.js +533 -467
  83. package/tests/hydration/compiled/server/portal.js +94 -107
  84. package/tests/hydration/compiled/server/reactivity.js +87 -64
  85. package/tests/hydration/compiled/server/return.js +1424 -1174
  86. package/tests/hydration/compiled/server/switch.js +268 -238
  87. package/tests/hydration/compiled/server/try.js +98 -87
  88. package/tests/hydration/components/{mixed-control-flow.ripple → mixed-control-flow.rsrx} +2 -2
  89. package/tests/hydration/components/{try.ripple → try.rsrx} +4 -2
  90. package/tests/hydration/mixed-control-flow.test.js +14 -0
  91. package/tests/hydration/nested-control-flow.test.js +50 -48
  92. package/tests/hydration/try.test.js +25 -0
  93. package/tests/server/__snapshots__/compiler.test.ripple.snap +0 -32
  94. package/tests/server/__snapshots__/compiler.test.rsrx.snap +95 -0
  95. package/tests/server/{compiler.test.ripple → compiler.test.rsrx} +0 -17
  96. package/tests/server/{html-nesting-validation.test.ripple → html-nesting-validation.test.rsrx} +3 -3
  97. package/tests/server/streaming-ssr.test.rsrx +115 -0
  98. package/tests/server/{style-identifier.test.ripple → style-identifier.test.rsrx} +1 -1
  99. package/tests/server/try.test.rsrx +503 -0
  100. package/tests/setup-server.js +1 -1
  101. package/tests/utils/compiler-compat-config.test.js +4 -4
  102. package/tests/utils/vite-plugin-config.test.js +1 -1
  103. package/tests/utils/vite-plugin-hmr.test.js +5 -5
  104. package/tsconfig.json +2 -0
  105. package/types/index.d.ts +13 -23
  106. package/types/server.d.ts +43 -16
  107. package/src/compiler/comment-utils.js +0 -91
  108. package/src/compiler/errors.js +0 -77
  109. package/src/compiler/identifier-utils.js +0 -80
  110. package/src/compiler/index.d.ts +0 -127
  111. package/src/compiler/index.js +0 -89
  112. package/src/compiler/phases/1-parse/index.js +0 -2964
  113. package/src/compiler/phases/1-parse/style.js +0 -704
  114. package/src/compiler/phases/2-analyze/css-analyze.js +0 -160
  115. package/src/compiler/phases/2-analyze/index.js +0 -2238
  116. package/src/compiler/phases/2-analyze/prune.js +0 -1131
  117. package/src/compiler/phases/2-analyze/validation.js +0 -168
  118. package/src/compiler/phases/3-transform/client/index.js +0 -5301
  119. package/src/compiler/phases/3-transform/segments.js +0 -2129
  120. package/src/compiler/phases/3-transform/server/index.js +0 -1899
  121. package/src/compiler/phases/3-transform/stylesheet.js +0 -545
  122. package/src/compiler/scope.js +0 -476
  123. package/src/compiler/source-map-utils.js +0 -358
  124. package/src/compiler/types/acorn.d.ts +0 -11
  125. package/src/compiler/types/estree-jsx.d.ts +0 -11
  126. package/src/compiler/types/estree.d.ts +0 -11
  127. package/src/compiler/types/index.d.ts +0 -1404
  128. package/src/compiler/types/parse.d.ts +0 -1721
  129. package/src/compiler/utils.js +0 -1263
  130. package/tests/client/_etc.test.ripple +0 -5
  131. package/tests/client/async-suspend.test.ripple +0 -94
  132. package/tests/client/try.test.ripple +0 -196
  133. package/tests/server/streaming-ssr.test.ripple +0 -68
  134. package/tests/server/try.test.ripple +0 -82
  135. /package/tests/client/array/{array.copy-within.test.ripple → array.copy-within.test.rsrx} +0 -0
  136. /package/tests/client/array/{array.derived.test.ripple → array.derived.test.rsrx} +0 -0
  137. /package/tests/client/array/{array.iteration.test.ripple → array.iteration.test.rsrx} +0 -0
  138. /package/tests/client/array/{array.mutations.test.ripple → array.mutations.test.rsrx} +0 -0
  139. /package/tests/client/array/{array.to-methods.test.ripple → array.to-methods.test.rsrx} +0 -0
  140. /package/tests/client/basic/{basic.attributes.test.ripple → basic.attributes.test.rsrx} +0 -0
  141. /package/tests/client/basic/{basic.collections.test.ripple → basic.collections.test.rsrx} +0 -0
  142. /package/tests/client/basic/{basic.components.test.ripple → basic.components.test.rsrx} +0 -0
  143. /package/tests/client/basic/{basic.events.test.ripple → basic.events.test.rsrx} +0 -0
  144. /package/tests/client/basic/{basic.get-set.test.ripple → basic.get-set.test.rsrx} +0 -0
  145. /package/tests/client/basic/{basic.hmr.test.ripple → basic.hmr.test.rsrx} +0 -0
  146. /package/tests/client/basic/{basic.reactivity.test.ripple → basic.reactivity.test.rsrx} +0 -0
  147. /package/tests/client/basic/{basic.rendering.test.ripple → basic.rendering.test.rsrx} +0 -0
  148. /package/tests/client/basic/{basic.utilities.test.ripple → basic.utilities.test.rsrx} +0 -0
  149. /package/tests/client/{boundaries.test.ripple → boundaries.test.rsrx} +0 -0
  150. /package/tests/client/compiler/{compiler.regex.test.ripple → compiler.regex.test.rsrx} +0 -0
  151. /package/tests/client/composite/{composite.dynamic-components.test.ripple → composite.dynamic-components.test.rsrx} +0 -0
  152. /package/tests/client/composite/{composite.generics.test.ripple → composite.generics.test.rsrx} +0 -0
  153. /package/tests/client/composite/{composite.props.test.ripple → composite.props.test.rsrx} +0 -0
  154. /package/tests/client/composite/{composite.reactivity.test.ripple → composite.reactivity.test.rsrx} +0 -0
  155. /package/tests/client/composite/{composite.render.test.ripple → composite.render.test.rsrx} +0 -0
  156. /package/tests/client/{computed-properties.test.ripple → computed-properties.test.rsrx} +0 -0
  157. /package/tests/client/{context.test.ripple → context.test.rsrx} +0 -0
  158. /package/tests/client/{date.test.ripple → date.test.rsrx} +0 -0
  159. /package/tests/client/{dynamic-elements.test.ripple → dynamic-elements.test.rsrx} +0 -0
  160. /package/tests/client/{events.test.ripple → events.test.rsrx} +0 -0
  161. /package/tests/client/{for.test.ripple → for.test.rsrx} +0 -0
  162. /package/tests/client/{function-overload-import.ripple → function-overload-import.rsrx} +0 -0
  163. /package/tests/client/{head.test.ripple → head.test.rsrx} +0 -0
  164. /package/tests/client/{html.test.ripple → html.test.rsrx} +0 -0
  165. /package/tests/client/{input-value.test.ripple → input-value.test.rsrx} +0 -0
  166. /package/tests/client/{lazy-destructuring.test.ripple → lazy-destructuring.test.rsrx} +0 -0
  167. /package/tests/client/{map.test.ripple → map.test.rsrx} +0 -0
  168. /package/tests/client/{media-query.test.ripple → media-query.test.rsrx} +0 -0
  169. /package/tests/client/{object.test.ripple → object.test.rsrx} +0 -0
  170. /package/tests/client/{portal.test.ripple → portal.test.rsrx} +0 -0
  171. /package/tests/client/{ref.test.ripple → ref.test.rsrx} +0 -0
  172. /package/tests/client/{set.test.ripple → set.test.rsrx} +0 -0
  173. /package/tests/client/{svg.test.ripple → svg.test.rsrx} +0 -0
  174. /package/tests/client/{switch.test.ripple → switch.test.rsrx} +0 -0
  175. /package/tests/client/{tsx.test.ripple → tsx.test.rsrx} +0 -0
  176. /package/tests/client/{typescript-generics.test.ripple → typescript-generics.test.rsrx} +0 -0
  177. /package/tests/client/url/{url.derived.test.ripple → url.derived.test.rsrx} +0 -0
  178. /package/tests/client/url/{url.parsing.test.ripple → url.parsing.test.rsrx} +0 -0
  179. /package/tests/client/url/{url.partial-removal.test.ripple → url.partial-removal.test.rsrx} +0 -0
  180. /package/tests/client/url/{url.reactivity.test.ripple → url.reactivity.test.rsrx} +0 -0
  181. /package/tests/client/url/{url.serialization.test.ripple → url.serialization.test.rsrx} +0 -0
  182. /package/tests/client/url-search-params/{url-search-params.derived.test.ripple → url-search-params.derived.test.rsrx} +0 -0
  183. /package/tests/client/url-search-params/{url-search-params.initialization.test.ripple → url-search-params.initialization.test.rsrx} +0 -0
  184. /package/tests/client/url-search-params/{url-search-params.iteration.test.ripple → url-search-params.iteration.test.rsrx} +0 -0
  185. /package/tests/client/url-search-params/{url-search-params.mutation.test.ripple → url-search-params.mutation.test.rsrx} +0 -0
  186. /package/tests/client/url-search-params/{url-search-params.retrieval.test.ripple → url-search-params.retrieval.test.rsrx} +0 -0
  187. /package/tests/client/url-search-params/{url-search-params.serialization.test.ripple → url-search-params.serialization.test.rsrx} +0 -0
  188. /package/tests/client/url-search-params/{url-search-params.tracked-url.test.ripple → url-search-params.tracked-url.test.rsrx} +0 -0
  189. /package/tests/hydration/components/{basic.ripple → basic.rsrx} +0 -0
  190. /package/tests/hydration/components/{composite.ripple → composite.rsrx} +0 -0
  191. /package/tests/hydration/components/{events.ripple → events.rsrx} +0 -0
  192. /package/tests/hydration/components/{for.ripple → for.rsrx} +0 -0
  193. /package/tests/hydration/components/{head.ripple → head.rsrx} +0 -0
  194. /package/tests/hydration/components/{hmr.ripple → hmr.rsrx} +0 -0
  195. /package/tests/hydration/components/{html-in-template.ripple → html-in-template.rsrx} +0 -0
  196. /package/tests/hydration/components/{html.ripple → html.rsrx} +0 -0
  197. /package/tests/hydration/components/{if-children.ripple → if-children.rsrx} +0 -0
  198. /package/tests/hydration/components/{if.ripple → if.rsrx} +0 -0
  199. /package/tests/hydration/components/{nested-control-flow.ripple → nested-control-flow.rsrx} +0 -0
  200. /package/tests/hydration/components/{portal.ripple → portal.rsrx} +0 -0
  201. /package/tests/hydration/components/{reactivity.ripple → reactivity.rsrx} +0 -0
  202. /package/tests/hydration/components/{return.ripple → return.rsrx} +0 -0
  203. /package/tests/hydration/components/{switch.ripple → switch.rsrx} +0 -0
  204. /package/tests/server/{await.test.ripple → await.test.rsrx} +0 -0
  205. /package/tests/server/{basic.attributes.test.ripple → basic.attributes.test.rsrx} +0 -0
  206. /package/tests/server/{basic.components.test.ripple → basic.components.test.rsrx} +0 -0
  207. /package/tests/server/{basic.test.ripple → basic.test.rsrx} +0 -0
  208. /package/tests/server/{composite.props.test.ripple → composite.props.test.rsrx} +0 -0
  209. /package/tests/server/{composite.test.ripple → composite.test.rsrx} +0 -0
  210. /package/tests/server/{context.test.ripple → context.test.rsrx} +0 -0
  211. /package/tests/server/{dynamic-elements.test.ripple → dynamic-elements.test.rsrx} +0 -0
  212. /package/tests/server/{for.test.ripple → for.test.rsrx} +0 -0
  213. /package/tests/server/{head.test.ripple → head.test.rsrx} +0 -0
  214. /package/tests/server/{if.test.ripple → if.test.rsrx} +0 -0
  215. /package/tests/server/{lazy-destructuring.test.ripple → lazy-destructuring.test.rsrx} +0 -0
  216. /package/tests/server/{return.test.ripple → return.test.rsrx} +0 -0
  217. /package/tests/server/{switch.test.ripple → switch.test.rsrx} +0 -0
@@ -1,4 +1,4 @@
1
- /** @import { Block, Component, Dependency, Derived, Tracked } from '#client' */
1
+ /** @import { Block, Component, Dependency, Derived, Tracked, BlockWithTryBoundaryAndCatch, DeferredTrackedEntry } from '#client' */
2
2
  /** @import { NAMESPACE_URI } from './constants.js' */
3
3
 
4
4
  import { DEV } from 'esm-env';
@@ -6,30 +6,42 @@ import {
6
6
  destroy_block,
7
7
  destroy_non_branch_children,
8
8
  effect,
9
- is_destroyed,
10
- render,
9
+ pause_block,
10
+ pre_effect,
11
11
  } from './blocks.js';
12
12
  import {
13
- ASYNC_BLOCK,
13
+ ASYNC_DERIVED_READ_THROWN,
14
14
  BLOCK_HAS_RUN,
15
15
  BRANCH_BLOCK,
16
16
  DERIVED,
17
17
  COMPUTED_PROPERTY,
18
18
  CONTAINS_TEARDOWN,
19
19
  CONTAINS_UPDATE,
20
- DEFERRED,
21
20
  DESTROYED,
22
21
  EFFECT_BLOCK,
23
22
  PAUSED,
23
+ PRE_EFFECT_BLOCK,
24
24
  ROOT_BLOCK,
25
25
  TRACKED,
26
- TRY_BLOCK,
27
26
  UNINITIALIZED,
28
27
  REF_PROP,
29
28
  TRACKED_OBJECT,
30
29
  DEFAULT_NAMESPACE,
30
+ DERIVED_UPDATED,
31
+ SUSPENSE_PENDING,
32
+ SUSPENSE_REJECTED,
33
+ TRY_BLOCK,
34
+ DIRECT_CHILD_BLOCK,
31
35
  } from './constants.js';
32
- import { capture, suspend } from './try.js';
36
+ import {
37
+ begin_boundary_request,
38
+ complete_boundary_request,
39
+ get_boundary_with_catch,
40
+ get_pending_boundary,
41
+ register_boundary_deferred,
42
+ register_boundary_paused_block,
43
+ replace_boundary_request,
44
+ } from './try.js';
33
45
  import {
34
46
  define_property,
35
47
  get_descriptor,
@@ -38,6 +50,7 @@ import {
38
50
  is_ripple_object,
39
51
  object_keys,
40
52
  } from './utils.js';
53
+ import { get_async_track_result } from '../../../utils/async.js';
41
54
 
42
55
  const FLUSH_MICROTASK = 0;
43
56
  const FLUSH_SYNC = 1;
@@ -55,7 +68,7 @@ export let active_namespace = DEFAULT_NAMESPACE;
55
68
  /** @type {boolean} */
56
69
  export let is_mutating_allowed = true;
57
70
 
58
- /** @type {Map<Tracked, any>} */
71
+ /** @type {Map<Tracked | Derived, any>} */
59
72
  var old_values = new Map();
60
73
 
61
74
  // Used for controlling the flush of blocks
@@ -72,6 +85,8 @@ let queued_root_blocks = [];
72
85
  let queued_microtasks = [];
73
86
  /** @type {number} */
74
87
  let flush_count = 0;
88
+ /** @type {(() => void)[]} */
89
+ var queued_post_block_flush = [];
75
90
  /** @type {null | Dependency} */
76
91
  let active_dependency = null;
77
92
 
@@ -141,7 +156,7 @@ export function run_teardown(block) {
141
156
 
142
157
  /**
143
158
  * @param {Block} block
144
- * @param {() => void} fn
159
+ * @param {() => any} fn
145
160
  */
146
161
  export function with_block(block, fn) {
147
162
  var prev_block = active_block;
@@ -172,6 +187,15 @@ function update_derived(computed) {
172
187
  }
173
188
  }
174
189
 
190
+ /**
191
+ * @param {Tracked} tracked
192
+ * @param {any} value
193
+ */
194
+ function update_tracked_value_clock(tracked, value) {
195
+ tracked.__v = value;
196
+ tracked.c = increment_clock();
197
+ }
198
+
175
199
  /**
176
200
  * @param {Derived} computed
177
201
  */
@@ -212,6 +236,20 @@ function run_derived(computed) {
212
236
  computed.d = active_dependency;
213
237
 
214
238
  return value;
239
+ } catch (error) {
240
+ computed.d = active_dependency;
241
+ if (error === ASYNC_DERIVED_READ_THROWN) {
242
+ // Check if any dependency is rejected — if so, propagate rejection
243
+ var dep = active_dependency;
244
+ while (dep !== null) {
245
+ if (dep.t.__v === SUSPENSE_REJECTED) {
246
+ return SUSPENSE_REJECTED;
247
+ }
248
+ dep = dep.n;
249
+ }
250
+ return SUSPENSE_PENDING;
251
+ }
252
+ throw error;
215
253
  } finally {
216
254
  active_block = previous_block;
217
255
  active_reaction = previous_reaction;
@@ -225,18 +263,13 @@ function run_derived(computed) {
225
263
  /**
226
264
  * @param {unknown} error
227
265
  * @param {Block} block
266
+ * @returns {BlockWithTryBoundaryAndCatch}
228
267
  */
229
268
  export function handle_error(error, block) {
230
- /** @type {Block | null} */
231
- var current = block;
232
-
233
- while (current !== null) {
234
- var state = current.s;
235
- if ((current.f & TRY_BLOCK) !== 0 && state.c !== null) {
236
- state.c(error);
237
- return;
238
- }
239
- current = current.p;
269
+ var boundary_with_catch = get_boundary_with_catch(block);
270
+ if (boundary_with_catch !== null) {
271
+ boundary_with_catch.s.c(error);
272
+ return boundary_with_catch;
240
273
  }
241
274
 
242
275
  throw error;
@@ -277,7 +310,53 @@ export function run_block(block) {
277
310
 
278
311
  block.d = active_dependency;
279
312
  } catch (error) {
280
- handle_error(error, block);
313
+ var is_component_direct = false;
314
+ var is_try_fn_block = false;
315
+ block.d = active_dependency;
316
+ // When a derived read throws ASYNC_DERIVED_READ_THROWN, it means the
317
+ // derived is still SUSPENSE_PENDING. The dependency was already registered,
318
+ // so we swallow the throw and let the parent continue processing. When
319
+ // the derived settles, the block will be dirty and rerun automatically.
320
+ if (error !== ASYNC_DERIVED_READ_THROWN) {
321
+ handle_error(error, block);
322
+ } else if (
323
+ // pending async tracked was read outside allowed blocks
324
+ (is_component_direct = active_component?.b === block) ||
325
+ (is_try_fn_block =
326
+ block.p !== null && (block.p.f & TRY_BLOCK) !== 0 && (block.f & DIRECT_CHILD_BLOCK) !== 0)
327
+ ) {
328
+ throw new Error(
329
+ `Reads on pending tracked values directly inside ${is_component_direct ? 'component' : 'try/pending/catch'} body are prohibited. Use trackPending() test or peek() for safe access or create another derived instead.`,
330
+ );
331
+ } else {
332
+ // pending async tracked was read and threw ASYNC_DERIVED_READ_THROWN
333
+ var boundary = get_pending_boundary(block);
334
+ if (boundary !== null) {
335
+ pause_block(block);
336
+ register_boundary_paused_block(boundary, block);
337
+
338
+ // Register deferred boundary completions for async tracked deps.
339
+ // This handles the case where a child boundary reads a tracked value
340
+ // whose resolution is managed by a different (parent) boundary.
341
+ var dep = block.d;
342
+ while (dep !== null) {
343
+ var dep_tracked = /** @type {Tracked} */ (dep.t);
344
+ if (
345
+ (dep_tracked.__v === SUSPENSE_PENDING || dep_tracked.__v === SUSPENSE_REJECTED) &&
346
+ (dep_tracked.f & TRACKED) !== 0
347
+ ) {
348
+ var deferred_req = begin_boundary_request(boundary);
349
+ var entry = /** @type {DeferredTrackedEntry} */ ({ b: boundary, r: deferred_req });
350
+ if (dep_tracked.d === null) {
351
+ dep_tracked.d = [entry];
352
+ } else {
353
+ dep_tracked.d.push(entry);
354
+ }
355
+ }
356
+ dep = dep.n;
357
+ }
358
+ }
359
+ }
281
360
  } finally {
282
361
  active_block = previous_block;
283
362
  active_reaction = previous_reaction;
@@ -289,6 +368,22 @@ export function run_block(block) {
289
368
 
290
369
  var empty_get_set = { get: undefined, set: undefined };
291
370
 
371
+ /**
372
+ * Complete all deferred boundary requests registered on a tracked value.
373
+ * @param {Tracked} t
374
+ * @param {boolean} [show_resolved=true]
375
+ */
376
+ function complete_deferred_boundaries(t, show_resolved = true) {
377
+ if (t.d !== null) {
378
+ for (var i = 0; i < t.d.length; i++) {
379
+ var entry = t.d[i];
380
+ complete_boundary_request(entry.b, entry.r, show_resolved);
381
+ }
382
+ t.d = null;
383
+ }
384
+ }
385
+
386
+ /** @type {Tracked} */
292
387
  class TrackedValue {
293
388
  /**
294
389
  * @param {any} v
@@ -299,35 +394,38 @@ class TrackedValue {
299
394
  this.a = a;
300
395
  this.b = block;
301
396
  this.c = 0;
397
+ /** @type {DeferredTrackedEntry[] | null} */
398
+ this.d = null;
302
399
  this.f = TRACKED;
303
400
  this.__v = v;
304
401
  }
305
402
  get [0]() {
306
- return get_tracked(/** @type {Tracked} */ (this));
403
+ return get_tracked(this);
307
404
  }
308
405
  set [0](v) {
309
- set(/** @type {Tracked} */ (this), v);
406
+ set(this, v);
310
407
  }
311
408
  get [1]() {
312
409
  return this;
313
410
  }
314
411
  get value() {
315
- return get_tracked(/** @type {Tracked} */ (this));
412
+ return get_tracked(this);
316
413
  }
317
414
  /** @param {any} v */
318
415
  set value(v) {
319
- set(/** @type {Tracked} */ (this), v);
416
+ set(this, v);
320
417
  }
321
418
  /** @returns {2} */
322
419
  get length() {
323
420
  return 2;
324
421
  }
325
422
  *[Symbol.iterator]() {
326
- yield get_tracked(/** @type {Tracked} */ (this));
423
+ yield get_tracked(this);
327
424
  yield this;
328
425
  }
329
426
  }
330
427
 
428
+ /** @type {Derived} */
331
429
  class DerivedValue {
332
430
  /**
333
431
  * @param {Function} fn
@@ -343,32 +441,32 @@ class DerivedValue {
343
441
  this.co = active_component;
344
442
  /** @type {null | Dependency} */
345
443
  this.d = null;
346
- this.f = TRACKED | DERIVED;
444
+ this.f = DERIVED;
347
445
  this.fn = fn;
348
446
  this.__v = UNINITIALIZED;
349
447
  }
350
448
  get [0]() {
351
- return get_derived(/** @type {Derived} */ (this));
449
+ return get_derived(this);
352
450
  }
353
451
  set [0](v) {
354
- set(/** @type {Derived} */ (this), v);
452
+ set(this, v);
355
453
  }
356
454
  get [1]() {
357
455
  return this;
358
456
  }
359
457
  get value() {
360
- return get_derived(/** @type {Derived} */ (this));
458
+ return get_derived(this);
361
459
  }
362
460
  /** @param {any} v */
363
461
  set value(v) {
364
- set(/** @type {Derived} */ (this), v);
462
+ set(this, v);
365
463
  }
366
464
  /** @returns {2} */
367
465
  get length() {
368
466
  return 2;
369
467
  }
370
468
  *[Symbol.iterator]() {
371
- yield get_derived(/** @type {Derived} */ (this));
469
+ yield get_derived(this);
372
470
  yield this;
373
471
  }
374
472
  }
@@ -426,6 +524,225 @@ export function track(v, get, set, b) {
426
524
  return tracked(v, b, get, set);
427
525
  }
428
526
 
527
+ /**
528
+ * @param {any} fn
529
+ * @param {Block} b
530
+ * @returns {Tracked | void}
531
+ */
532
+ export function track_async(fn, b) {
533
+ if (is_ripple_object(fn)) {
534
+ return fn;
535
+ }
536
+
537
+ var target_block = b || active_block;
538
+ if (target_block === null) {
539
+ throw new TypeError('trackAsync() requires a valid component context');
540
+ }
541
+
542
+ if (typeof fn !== 'function') {
543
+ throw new TypeError(
544
+ 'trackAsync() only accepts function arguments that return a promise or an object with a promise property',
545
+ );
546
+ }
547
+
548
+ var t = tracked(SUSPENSE_PENDING, target_block);
549
+
550
+ // Capture the call-site block for boundary lookups. target_block is the
551
+ // component's block (passed by compiler), but the actual try/pending/catch
552
+ // boundary is an ancestor of active_block (the block executing trackAsync).
553
+ var call_site_block = /** @type {Block} */ (active_block);
554
+
555
+ var version = 0;
556
+ /** @type {AbortController | null} */
557
+ var abort_controller = null;
558
+ var request_id = 0;
559
+ /** @type {Block | null} */
560
+ var boundary = null;
561
+
562
+ // Find boundary from the call-site block.
563
+ boundary = get_pending_boundary(active_block);
564
+ if (boundary === null) {
565
+ throw new Error('Missing parent `try { ... } pending { ... }` statement');
566
+ }
567
+
568
+ request_id = begin_boundary_request(boundary);
569
+
570
+ pre_effect(() => {
571
+ var current_version = ++version;
572
+
573
+ // Abort previous in-flight request
574
+ if (abort_controller !== null && abort_controller.signal.aborted === false) {
575
+ abort_controller.abort(DERIVED_UPDATED);
576
+ }
577
+ abort_controller = null;
578
+
579
+ // Manage boundary request: replace if in-flight, or begin new if previous completed
580
+ if (request_id > 0 && boundary !== null) {
581
+ request_id = replace_boundary_request(boundary, request_id);
582
+ } else if (boundary !== null) {
583
+ request_id = begin_boundary_request(boundary);
584
+ }
585
+
586
+ // Set to pending before calling fn() in case it's sync
587
+ if (t.__v !== SUSPENSE_PENDING) {
588
+ update_tracked_value_clock(t, SUSPENSE_PENDING);
589
+ schedule_update(t.b);
590
+ }
591
+
592
+ // Temporarily allow mutations so set() doesn't throw inside the pre-effect
593
+ var previous_is_mutating_allowed = is_mutating_allowed;
594
+ is_mutating_allowed = true;
595
+
596
+ var result;
597
+ try {
598
+ result = fn();
599
+ } catch (e) {
600
+ is_mutating_allowed = previous_is_mutating_allowed;
601
+ if (e === ASYNC_DERIVED_READ_THROWN) {
602
+ // A dependency is still pending or rejected (e.g. chained trackAsync).
603
+ // Check if any dependency is rejected — if so, propagate rejection.
604
+ var dep = active_dependency;
605
+ while (dep !== null) {
606
+ if (dep.t.__v === SUSPENSE_REJECTED) {
607
+ update_tracked_value_clock(t, SUSPENSE_REJECTED);
608
+ schedule_update(t.b);
609
+ complete_deferred_boundaries(t, false);
610
+ if (request_id > 0 && boundary !== null) {
611
+ complete_boundary_request(boundary, request_id, false);
612
+ request_id = 0;
613
+ }
614
+ return;
615
+ }
616
+ dep = dep.n;
617
+ }
618
+ // Dependencies are pending, not rejected — register deferred
619
+ // rejection so that if the boundary goes to catch mode, this
620
+ // tracked value is also set to REJECTED.
621
+ if (request_id > 0 && boundary !== null) {
622
+ register_boundary_deferred(boundary, request_id, () => {
623
+ update_tracked_value_clock(t, SUSPENSE_REJECTED);
624
+ });
625
+ }
626
+ return;
627
+ }
628
+ throw e;
629
+ }
630
+ is_mutating_allowed = previous_is_mutating_allowed;
631
+
632
+ // Check if the result is async
633
+ var previous_tracking = tracking;
634
+ tracking = false;
635
+ var async_result = get_async_track_result(result);
636
+ tracking = previous_tracking;
637
+
638
+ if (async_result === null) {
639
+ // Sync result
640
+ update_tracked_value_clock(t, result);
641
+ schedule_update(t.b);
642
+ if (request_id > 0 && boundary !== null) {
643
+ complete_boundary_request(boundary, request_id);
644
+ request_id = 0;
645
+ }
646
+ return;
647
+ }
648
+
649
+ // Capture per-invocation so async closures (rejection handler, teardown)
650
+ // have a stable reference. The shared abort_controller is only read
651
+ // synchronously at the top of the pre_effect to abort the previous request.
652
+ var current_abort_controller = async_result.abort_controller;
653
+ abort_controller = current_abort_controller;
654
+
655
+ async_result.promise.then(
656
+ (resolved) => {
657
+ if (current_version !== version) {
658
+ // stale
659
+ return;
660
+ }
661
+ update_tracked_value_clock(t, resolved);
662
+ schedule_update(t.b);
663
+ complete_deferred_boundaries(t);
664
+ if (request_id > 0 && boundary !== null) {
665
+ complete_boundary_request(boundary, request_id);
666
+ request_id = 0;
667
+ }
668
+ },
669
+ (error) => {
670
+ if (current_version !== version) return; // stale
671
+
672
+ var is_internal_abort =
673
+ error === DERIVED_UPDATED || current_abort_controller?.signal?.reason === DERIVED_UPDATED;
674
+ if (is_internal_abort) {
675
+ // Internal abort (superseded by a new request) — don't set rejected
676
+ if (request_id > 0 && boundary !== null) {
677
+ complete_boundary_request(boundary, request_id, false);
678
+ request_id = 0;
679
+ }
680
+ complete_deferred_boundaries(t, false);
681
+ return;
682
+ }
683
+
684
+ update_tracked_value_clock(t, SUSPENSE_REJECTED);
685
+ schedule_update(t.b);
686
+ complete_deferred_boundaries(t, false);
687
+
688
+ // Route error to catch boundary
689
+ var boundary_with_catch = get_boundary_with_catch(call_site_block);
690
+ if (boundary_with_catch !== null) {
691
+ boundary_with_catch.s.c(error);
692
+ }
693
+
694
+ if (request_id > 0 && boundary !== null) {
695
+ var should_show_resolved =
696
+ boundary_with_catch === boundary || boundary === null ? false : true;
697
+ complete_boundary_request(boundary, request_id, should_show_resolved);
698
+ request_id = 0;
699
+ }
700
+ },
701
+ );
702
+
703
+ return () => {
704
+ // Teardown: abort in-flight request when block is destroyed
705
+ if (current_abort_controller !== null && current_abort_controller.signal.aborted === false) {
706
+ current_abort_controller.abort(DERIVED_UPDATED);
707
+ }
708
+ };
709
+ });
710
+
711
+ return t;
712
+ }
713
+
714
+ /**
715
+ * @param {(Derived | Tracked) | (() => any)} tracked
716
+ * @returns {boolean}
717
+ */
718
+ export function is_tracked_pending(tracked) {
719
+ try {
720
+ if (typeof tracked === 'function') {
721
+ tracked();
722
+ } else {
723
+ get(tracked);
724
+ }
725
+ return false;
726
+ } catch (error) {
727
+ if (error === ASYNC_DERIVED_READ_THROWN) {
728
+ return true;
729
+ }
730
+ throw error;
731
+ }
732
+ }
733
+
734
+ /**
735
+ * @param {Tracked | Derived} tracked
736
+ * @return {any}
737
+ */
738
+ export function peek_tracked(tracked) {
739
+ if (!is_ripple_object(tracked)) {
740
+ return tracked;
741
+ }
742
+
743
+ return tracked.__v;
744
+ }
745
+
429
746
  /**
430
747
  * @param {Tracked | Derived} tracked
431
748
  * @returns {Dependency}
@@ -461,7 +778,15 @@ function is_tracking_dirty(tracking) {
461
778
  var tracked = tracking.t;
462
779
 
463
780
  if ((tracked.f & DERIVED) !== 0) {
464
- update_derived(/** @type {Derived} **/ (tracked));
781
+ try {
782
+ update_derived(/** @type {Derived} **/ (tracked));
783
+ } catch (e) {
784
+ if (e === ASYNC_DERIVED_READ_THROWN) {
785
+ // The derived depends on a pending async value — treat as dirty
786
+ return true;
787
+ }
788
+ throw e;
789
+ }
465
790
  }
466
791
 
467
792
  if (tracked.c > tracking.c) {
@@ -490,77 +815,6 @@ export function is_block_dirty(block) {
490
815
  return is_tracking_dirty(block.d);
491
816
  }
492
817
 
493
- /**
494
- * @param {() => Promise<any>} fn
495
- * @param {Block} block
496
- * @returns {Promise<Tracked>}
497
- */
498
- export function async_computed(fn, block) {
499
- /** @type {Block | Derived | null} */
500
- let parent = active_reaction;
501
- var t = tracked(UNINITIALIZED, block);
502
- /** @type {Promise<any>} */
503
- var promise;
504
- /** @type {Map<Tracked, {v: any, c: number}>} */
505
- var new_values = new Map();
506
-
507
- render(
508
- () => {
509
- var [current, deferred] = capture_deferred(() => (promise = fn()));
510
-
511
- var restore = capture();
512
- /** @type {(() => void) | undefined} */
513
- var unsuspend;
514
-
515
- if (deferred === null) {
516
- unsuspend = suspend();
517
- } else {
518
- for (var i = 0; i < deferred.length; i++) {
519
- var tracked = deferred[i];
520
- new_values.set(tracked, { v: tracked.__v, c: tracked.c });
521
- }
522
- }
523
-
524
- promise.then((v) => {
525
- if (parent && is_destroyed(/** @type {Block} */ (parent))) {
526
- return;
527
- }
528
- if (promise === current && t.__v !== v) {
529
- restore();
530
-
531
- if (t.__v === UNINITIALIZED) {
532
- t.__v = v;
533
- } else {
534
- set(t, v);
535
- }
536
- }
537
-
538
- if (deferred === null) {
539
- unsuspend?.();
540
- } else if (promise === current) {
541
- for (var i = 0; i < deferred.length; i++) {
542
- var tracked = deferred[i];
543
- var stored = /** @type {{ v: any, c: number }} */ (new_values.get(tracked));
544
- var { v, c } = stored;
545
- tracked.__v = v;
546
- tracked.c = c;
547
- schedule_update(tracked.b);
548
- }
549
- new_values.clear();
550
- }
551
- });
552
- },
553
- null,
554
- ASYNC_BLOCK,
555
- );
556
-
557
- return new Promise(async (resolve) => {
558
- var p;
559
- while (p !== (p = promise)) await p;
560
- return resolve(t);
561
- });
562
- }
563
-
564
818
  /**
565
819
  * @template V
566
820
  * @param {Function} fn
@@ -576,29 +830,6 @@ function trigger_track_get(fn, v) {
576
830
  }
577
831
  }
578
832
 
579
- /**
580
- * @param {() => any} fn
581
- * @returns {[any, Tracked[] | null]}
582
- */
583
- function capture_deferred(fn) {
584
- var value = fn();
585
- /** @type {Tracked[] | null} */
586
- var deferred = null;
587
- var dependency = active_dependency;
588
-
589
- while (dependency !== null) {
590
- var tracked = dependency.t;
591
- if ((tracked.f & DEFERRED) !== 0) {
592
- deferred ??= [];
593
- deferred.push(tracked);
594
- break;
595
- }
596
- dependency = dependency.n;
597
- }
598
-
599
- return [value, deferred];
600
- }
601
-
602
833
  /**
603
834
  * @param {Block} root_block
604
835
  */
@@ -606,6 +837,8 @@ function flush_updates(root_block) {
606
837
  /** @type {Block | null} */
607
838
  var current = root_block;
608
839
  var containing_update = null;
840
+ var pre_effects = [];
841
+ var other_blocks = [];
609
842
  var effects = [];
610
843
  var containing_update_head = null;
611
844
 
@@ -619,16 +852,12 @@ function flush_updates(root_block) {
619
852
  }
620
853
 
621
854
  if ((flags & PAUSED) === 0 && containing_update !== null) {
622
- if ((flags & EFFECT_BLOCK) !== 0) {
855
+ if ((flags & PRE_EFFECT_BLOCK) !== 0) {
856
+ pre_effects.push(current);
857
+ } else if ((flags & EFFECT_BLOCK) !== 0) {
623
858
  effects.push(current);
624
859
  } else {
625
- try {
626
- if (is_block_dirty(current)) {
627
- run_block(current);
628
- }
629
- } catch (error) {
630
- handle_error(error, current);
631
- }
860
+ other_blocks.push(current);
632
861
  }
633
862
  /** @type {Block | null} */
634
863
  var child = current.first;
@@ -654,18 +883,47 @@ function flush_updates(root_block) {
654
883
  }
655
884
  }
656
885
 
657
- var length = effects.length;
886
+ var arr_length = 0;
887
+
888
+ // Phase 1: pre-effects (e.g. update tracked values before render blocks read them)
889
+ arr_length = pre_effects.length;
890
+ for (var i = 0; i < arr_length; i++) {
891
+ var block = pre_effects[i];
892
+
893
+ try {
894
+ if ((block.f & (PAUSED | DESTROYED)) === 0 && is_block_dirty(block)) {
895
+ run_block(block);
896
+ }
897
+ } catch (error) {
898
+ handle_error(error, block);
899
+ }
900
+ }
901
+
902
+ // Phase 2: all other blocks except effects
903
+ arr_length = other_blocks.length;
904
+ for (var i = 0; i < arr_length; i++) {
905
+ var block = other_blocks[i];
906
+
907
+ try {
908
+ if ((block.f & (PAUSED | DESTROYED)) === 0 && is_block_dirty(block)) {
909
+ run_block(block);
910
+ }
911
+ } catch (error) {
912
+ handle_error(error, block);
913
+ }
914
+ }
658
915
 
659
- for (var i = 0; i < length; i++) {
660
- var effect = effects[i];
661
- var flags = effect.f;
916
+ // Phase 3: effects
917
+ arr_length = effects.length;
918
+ for (var i = 0; i < arr_length; i++) {
919
+ var block = effects[i];
662
920
 
663
921
  try {
664
- if ((flags & (PAUSED | DESTROYED)) === 0 && is_block_dirty(effect)) {
665
- run_block(effect);
922
+ if ((block.f & (PAUSED | DESTROYED)) === 0 && is_block_dirty(block)) {
923
+ run_block(block);
666
924
  }
667
925
  } catch (error) {
668
- handle_error(error, effect);
926
+ handle_error(error, block);
669
927
  }
670
928
  }
671
929
  }
@@ -677,6 +935,14 @@ function flush_queued_root_blocks(root_blocks) {
677
935
  for (let i = 0; i < root_blocks.length; i++) {
678
936
  flush_updates(root_blocks[i]);
679
937
  }
938
+
939
+ if (queued_post_block_flush.length > 0) {
940
+ var callbacks = queued_post_block_flush;
941
+ queued_post_block_flush = [];
942
+ for (var j = 0; j < callbacks.length; j++) {
943
+ callbacks[j]();
944
+ }
945
+ }
680
946
  }
681
947
 
682
948
  /**
@@ -702,8 +968,9 @@ function flush_microtasks() {
702
968
 
703
969
  flush_count++;
704
970
  if (flush_count > 1001) {
705
- flush_count = 0;
706
- return;
971
+ throw new Error(
972
+ 'Maximum update depth exceeded. This typically indicates that an effect reads and writes the same piece of state.',
973
+ );
707
974
  }
708
975
  var previous_queued_root_blocks = queued_root_blocks;
709
976
  queued_root_blocks = [];
@@ -728,6 +995,16 @@ export function queue_microtask(fn) {
728
995
  }
729
996
  }
730
997
 
998
+ /**
999
+ * Queue a callback to run after all root blocks are flushed.
1000
+ * Used to defer boundary completions so chained async deriveds evaluated during
1001
+ * the flush can start new requests before the boundary transitions out of pending.
1002
+ * @param {() => void} fn
1003
+ */
1004
+ export function queue_post_block_flush_callback(fn) {
1005
+ queued_post_block_flush.push(fn);
1006
+ }
1007
+
731
1008
  /**
732
1009
  * @param {Block} block
733
1010
  */
@@ -751,7 +1028,7 @@ export function schedule_update(block) {
751
1028
  }
752
1029
 
753
1030
  /**
754
- * @param {Tracked} tracked
1031
+ * @param {Tracked | Derived} tracked
755
1032
  */
756
1033
  function register_dependency(tracked) {
757
1034
  var dependency = active_dependency;
@@ -787,12 +1064,18 @@ export function get_derived(computed) {
787
1064
  if (tracking) {
788
1065
  register_dependency(computed);
789
1066
  }
1067
+ var value = computed.__v;
790
1068
  var get = computed.a.get;
791
1069
  if (get !== undefined) {
792
- computed.__v = trigger_track_get(get, computed.__v);
1070
+ value = trigger_track_get(get, value);
1071
+ computed.__v = value;
793
1072
  }
794
1073
 
795
- return computed.__v;
1074
+ if (value === SUSPENSE_PENDING || value === SUSPENSE_REJECTED) {
1075
+ throw ASYNC_DERIVED_READ_THROWN;
1076
+ }
1077
+
1078
+ return value;
796
1079
  }
797
1080
 
798
1081
  /**
@@ -806,7 +1089,7 @@ export function get(tracked) {
806
1089
 
807
1090
  return (tracked.f & DERIVED) !== 0
808
1091
  ? get_derived(/** @type {Derived} */ (tracked))
809
- : get_tracked(tracked);
1092
+ : get_tracked(/** @type {Tracked} */ (tracked));
810
1093
  }
811
1094
 
812
1095
  /**
@@ -817,6 +1100,11 @@ export function get_tracked(tracked) {
817
1100
  if (tracking) {
818
1101
  register_dependency(tracked);
819
1102
  }
1103
+
1104
+ if (value === SUSPENSE_PENDING || value === SUSPENSE_REJECTED) {
1105
+ throw ASYNC_DERIVED_READ_THROWN;
1106
+ }
1107
+
820
1108
  if (teardown && old_values.has(tracked)) {
821
1109
  value = old_values.get(tracked);
822
1110
  }
@@ -1203,6 +1491,7 @@ export function safe_scope(err = 'Cannot access outside of a component context')
1203
1491
 
1204
1492
  export function create_component_ctx() {
1205
1493
  return {
1494
+ b: active_block,
1206
1495
  c: null,
1207
1496
  e: null,
1208
1497
  m: false,
@@ -1304,29 +1593,3 @@ export function exclude_from_object(obj, exclude_keys) {
1304
1593
 
1305
1594
  return new_obj;
1306
1595
  }
1307
-
1308
- /**
1309
- * @param {any} v
1310
- * @returns {Promise<() => any>}
1311
- */
1312
- export async function maybe_tracked(v) {
1313
- var restore = capture();
1314
- let value;
1315
-
1316
- if (is_ripple_object(v)) {
1317
- if ((v.f & DERIVED) !== 0) {
1318
- value = await async_computed(v.fn, v.b);
1319
- } else {
1320
- value = await async_computed(async () => {
1321
- return await get_tracked(v);
1322
- }, /** @type {Block} */ (active_block));
1323
- }
1324
- } else {
1325
- value = await v;
1326
- }
1327
-
1328
- return () => {
1329
- restore();
1330
- return value;
1331
- };
1332
- }