|
1 | | -/** @import { Source } from '#client' */ |
2 | | -import { without_reactive_context } from '../internal/client/dom/elements/bindings/shared.js'; |
| 1 | +/** @import { Source, Derived, Effect } from '#client' */ |
| 2 | +import { DERIVED } from '../internal/client/constants.js'; |
3 | 3 | import { derived } from '../internal/client/index.js'; |
4 | 4 | import { source, set } from '../internal/client/reactivity/sources.js'; |
5 | | -import { get } from '../internal/client/runtime.js'; |
| 5 | +import { active_reaction, get, set_active_reaction } from '../internal/client/runtime.js'; |
6 | 6 |
|
7 | 7 | var inited = false; |
8 | 8 |
|
| 9 | +/** |
| 10 | + * @template T |
| 11 | + * @param {() => T} fn |
| 12 | + * @returns {T} |
| 13 | + */ |
| 14 | +function with_parent_effect(fn) { |
| 15 | + var previous_reaction = active_reaction; |
| 16 | + var parent_reaction = active_reaction; |
| 17 | + |
| 18 | + while (parent_reaction !== null) { |
| 19 | + if ((parent_reaction.f & DERIVED) === 0) { |
| 20 | + break; |
| 21 | + } |
| 22 | + parent_reaction = /** @type {Derived | Effect} */ (parent_reaction).parent; |
| 23 | + } |
| 24 | + |
| 25 | + set_active_reaction(parent_reaction); |
| 26 | + try { |
| 27 | + return fn(); |
| 28 | + } finally { |
| 29 | + set_active_reaction(previous_reaction); |
| 30 | + } |
| 31 | +} |
| 32 | + |
9 | 33 | export class SvelteDate extends Date { |
10 | 34 | #time = source(super.getTime()); |
11 | 35 |
|
@@ -44,10 +68,10 @@ export class SvelteDate extends Date { |
44 | 68 | var d = this.#deriveds.get(method); |
45 | 69 |
|
46 | 70 | if (d === undefined) { |
47 | | - // We don't want to associate the derived with the current |
48 | | - // reactive context, as that means the derived will get destroyed |
49 | | - // each time it re-fires |
50 | | - d = without_reactive_context(() => |
| 71 | + // Ensure we create the derived inside the nearest parent effect if |
| 72 | + // we're inside a derived, otherwise the derived will be destroyed each |
| 73 | + // time it re-runs |
| 74 | + d = with_parent_effect(() => |
51 | 75 | derived(() => { |
52 | 76 | get(this.#time); |
53 | 77 | // @ts-ignore |
|
0 commit comments