-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Svelte 5 Runes mode #51
base: master
Are you sure you want to change the base?
Conversation
src/Time.svelte
Outdated
|
||
import { dayjs } from "./dayjs"; | ||
import { onMount } from "svelte"; | ||
|
||
/** @type {undefined | NodeJS.Timeout} */ | ||
let interval = undefined; | ||
let liveUpdate = $state(0); | ||
|
||
const DEFAULT_INTERVAL = 60 * 1_000; | ||
|
||
onMount(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like this should be called onDestroy https://svelte.dev/docs/svelte/lifecycle-hooks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually would be better to move it into $effect
$effect(() => {
// This will be recreated whenever `milliseconds` changes
const interval = setInterval(() => {
count += 1;
}, milliseconds);
return () => {
// if a callback is provided, it will run
// a) immediately before the effect re-runs
// b) when the component is destroyed
clearInterval(interval);
};
});
```
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch. that should be easy. i'll have a look tomorrow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i have updated the code to return the clearInterval
in $effect
return statement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, I think we could clean up the onmount and use the function return of $effect
cc @metonym |
src/Time.svelte
Outdated
|
||
import { dayjs } from "./dayjs"; | ||
import { onMount } from "svelte"; | ||
|
||
/** @type {undefined | NodeJS.Timeout} */ | ||
let interval = undefined; | ||
let liveUpdate = $state(0); | ||
|
||
const DEFAULT_INTERVAL = 60 * 1_000; | ||
|
||
onMount(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch. that should be easy. i'll have a look tomorrow.
src/Time.svelte
Outdated
let formatted = $derived.by(() => { | ||
liveUpdate; // no-op. this is a dependency trigger for live updates | ||
return relative ? dayjs(timestamp).from() : dayjs(timestamp).format(format); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that we need the liveUpdate
$state rune b/c if any of the props change, formatted
should get updated (i think...). it is something i can test. if not, this would simplify some things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i have removed liveUpdate as it does not have any adverse impacts on live updates.
$effect(() => { | ||
/** @type {undefined | NodeJS.Timeout} */ | ||
let interval; | ||
if (relative && live !== false) { | ||
interval = setInterval( | ||
() => { | ||
formatted = dayjs(timestamp).from(); | ||
}, | ||
Math.abs(typeof live === "number" ? live : DEFAULT_INTERVAL), | ||
); | ||
} | ||
return () => clearInterval(interval); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait how does this even work. If this is setting formatted, but formatted is derived. Guessing this one takes over the derived instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good call. it does work, but i agree, it doesn't makes sense for me to update a derived value. i'm thinking formatted
should be a $state
instead of a $derived
. if that makes sense, let me know and i will update.
but, in this instance, the derived will only be updated if relative
, live
, or timestamp
ever change, which, most likely, they won't change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either is fine, I think that if we update it the initial state needs to be set in the effect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i found that in $effect
any values that are read asynchronously, for example in a setInterval
, will not be tracked.
https://svelte.dev/docs/svelte/$effect#Understanding-dependencies
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with what i found out above, i'm thinking to either keep it the way it is or change formatted
to use $state
instead of $derived
. let me know your thoughts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably using state would be good, whatever keeps it simple and easy to understand
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, left one comment.
@metonym can we get a new release and this merged? Is there anything else that should be updated like Dayjs? |
Nice work, thanks both. Will review – I think one thing that'll need updating is the demo, for which it breaks entirely for Svelte 5. It could be a nice opportunity to switch to Vite instead of Rollup. |
@metonym can we get this merged and that gets followed up on? |
… a svelte field in their package.json but no exports condition for svelte. svelte-time@0.9.0 Please see https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/faq.md#missing-exports-condition for details.
I've updated and ran the examples. I could successfully run and verify sveltekit and vite. I ran into issues with the following examples:
Any help would be appreciated. |
package.json
Outdated
".": { | ||
"svelte": "./src/index.js" | ||
} | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This exports
condition is not needed, as it's dynamically generated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed. i originally added it due to a compiler warning
This pull request provides support for Svelte 5 runes mode. It is not backwards compatible for Svelte 4.
Summary of changes:
Closes #48