fix: set correct parent for lazily created derived inside SvelteDate

pull/18509/head
Wey 1 week ago committed by JY Wey
parent 5edd8b0602
commit 49c9d682a4

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: set correct parent for lazily created derived inside SvelteDate

@ -2,7 +2,13 @@
import { derived } from '../internal/client/index.js';
import { set, state } from '../internal/client/reactivity/sources.js';
import { tag } from '../internal/client/dev/tracing.js';
import { active_reaction, get, set_active_reaction } from '../internal/client/runtime.js';
import {
active_effect,
active_reaction,
get,
set_active_effect,
set_active_reaction
} from '../internal/client/runtime.js';
import { DEV } from 'esm-env';
var inited = false;
@ -46,6 +52,7 @@ export class SvelteDate extends Date {
#deriveds = new Map();
#reaction = active_reaction;
#effect = active_effect;
/** @param {any[]} params */
constructor(...params) {
@ -87,7 +94,9 @@ export class SvelteDate extends Date {
// lazily create the derived, but as though it were being
// created at the same time as the class instance
const reaction = active_reaction;
const effect = active_effect;
set_active_reaction(this.#reaction);
set_active_effect(this.#effect);
d = derived(() => {
get(this.#time);
@ -102,6 +111,7 @@ export class SvelteDate extends Date {
this.#deriveds.set(method, d);
set_active_reaction(reaction);
set_active_effect(effect);
}
return get(d);

@ -0,0 +1,8 @@
<script>
let { event, clock } = $props();
const age = $derived(clock.compactAgo(event.timestamp));
const label = $derived(`#${event.id}`);
</script>
<span>{label} {age}</span>

@ -0,0 +1,16 @@
import { flushSync } from '../../../../src/index-client';
import { test } from '../../test';
export default test({
mode: ['client'],
async test({ assert, target }) {
debugger;
assert.htmlEqual(target.innerHTML, '<ul></ul>');
await new Promise((r) => setTimeout(r, 110));
assert.htmlEqual(target.innerHTML, '<ul><span>#1 0</span></ul>');
await new Promise((r) => setTimeout(r, 110));
assert.htmlEqual(target.innerHTML, '<ul><span>#2 0</span><span>#1 1</span></ul>');
await new Promise((r) => setTimeout(r, 110));
assert.htmlEqual(target.innerHTML, '<ul><span>#3 0</span><span>#2 1</span></ul>');
}
});

@ -0,0 +1,59 @@
<script>
import { createSubscriber, SvelteDate } from 'svelte/reactivity';
import Row from './Row.svelte';
function compactAgo(timestamp, now) {
const seconds = Math.max(0, Math.round((now - Date.parse(timestamp)) / 100));
debugger
return seconds;
}
class RelativeClock {
#now = new SvelteDate();
#subscribe;
constructor() {
this.tick();
this.#subscribe = createSubscriber(() => {
this.tick();
const interval = setInterval(this.tick, 100);
return () => {
clearInterval(interval)
};
});
}
tick = () => this.#now.setTime(Date.now());
compactAgo(timestamp) {
this.#subscribe();
return compactAgo(timestamp, this.#now.getTime());
}
}
let events = $state([]);
let nextId = $state(1);
let maxRows = 2;
const clock = new RelativeClock();
function addEvent() {
events.unshift({ id: nextId, timestamp: new Date().toISOString() });
nextId += 1;
while (events.length > maxRows) {
events.pop();
}
}
$effect(() => {
const interval = setInterval(addEvent, 100);
return () => {
clearInterval(interval);
}
});
</script>
<ul>
{#each events as event (event.id)}
<Row {event} {clock} />
{/each}
</ul>
Loading…
Cancel
Save