-
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
feat!: support Svelte 5 #51
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? |
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
@metonym can we get this merged? |
@niemyjski See my comment: #48 (comment) |
I'm reviewing this now, and pushing my changes:
My todo:
|
… 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.
… 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.
Another change b40a4bf I've updated the Svelte action to use
The file extension was updated to |
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've also got the demo working again using Astro, as another affirmation that the established examples work with Svelte 5 + Runes mode.
I went through each example
, linking it locally and making sure it could run. I wasn't able to quite link the Webpack 5 example, so I ended up testing it manually via copy/paste.
I also cut a stable v1 release on the existing master branch. This PR will be a v2.
I also updated the README in this PR, making an explicit note that going v2+ is Svelte 5 only, while Svelte 3/4 should use v1.
@kvangrae @niemyjski Thanks for your patience and all the work that went into this! Released in v2.0.0 After release, I've done the following:
|
Thank you!!! |
This pull request provides support for Svelte 5 runes mode. It is not backwards compatible for Svelte 4.
Summary of changes:
Closes #48