Remote Functions
#13986PR for https://github.com/sveltejs/kit/discussions/13897, discussion should happen there.
For a more complete commit history (with lots of explorations and dead ends; also includes some caching ideas) see #13957
pnpm test
and lint the project with pnpm lint
and pnpm check
pnpm changeset
and following the prompts. Changesets that add features should be minor
and those that fix bugs should be patch
. Please prefix changeset messages with feat:
, fix:
, or chore:
.Latest commit: 4706f36
Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.
When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types
Click here to learn what changesets are, and how to add one.
Click here if you're a maintainer who wants to add a changeset to this PR
The RemoteForm<Success, Failure>
thing feels weird to me — can we just get rid of fail
in this context? It's much simpler if people just return whatever shapes they want and do the necessary type narrowing in the component.
We might need to add event.setStatus
first though
Note to whoever implements it: We want to have something like event.version
or event.current
which contains the version the remote function caller has. The idea is that when an outdated client sends a request to a newer backend that this circumstance is detectable. Additionally we add reload()
which throws and signals the client to - well - reload. Calling it during a full page request (the first one) would be an error because you cannot reload at that point.
Personally I would be ok with that landing in a separate PR, shouldn't block this IMO.
Gonna update the behaviour of forms around errors, because it's slightly inconsistent at present. On a form that doesn't use .enhance(...)
, if a submission errors then the nearest +error.svelte
component is rendered. On a form that does use .enhance(...)
, the nearest +error.svelte
page is rendered if JavaScript isn't available, otherwise myForm.error
is populated, regardless of whatever error handling logic exists within the enhance
callback (which is slightly weird in the case where you try-catch and either handle it or throw a different error).
Aside from the inconsistency, the most likely outcome of this is that errors will just end up getting swallowed, as developers forget to add {#if myForm.error}
UI. I'm therefore going to change it so that the nearest +error.svelte
is always rendered if there's an unhandled error.
If you try-catch the submit()
call, you can (and should, since showing the error page is the second worst outcome behind a silent failure) handle the error however you choose in the progressively enhanced case.
Am second-guessing the my_form.for(key)
API — I'm having a rather hard time coming up with a good/non-contrived example of what to use it for. (The current example has 'something went wrong' suggesting a 5xx error, but in that case surely you wouldn't return at all?)
For validation errors it feels like you could rely on client-side validation (including things like minlength
) for the vast majority of things. AFAICT you only really need an independent result
property when you need to show validation errors/previously-submitted data, can't use client-side validation to prevent the bad submission in the first place, and need per-instance UI. I'm sure those cases do exist but I'm having such a struggle thinking of a realistic one that I'm just going to punt on it for now and remove that section of the docs
I think we need to come up with a better name than formAction
. It's weird for that object to contain a formAction
property, and also weird that something called formAction
contains a bunch of other properties. It also feels a bit weird to pick the camelCased property name over the lowercased attribute name, when the attribute is the thing that gives forms their magical progressive enhancement powers.
Looking at MDN, the only obvious alternative is override
, though that's perhaps a bit overloaded.
(I'm tempted to suggest just throwing formaction
onto the form object itself, alongside action
, so that you can use it on a <form>
or a <button>
. That might offend purists though.)
Also we should probably have formmethod
on there as well
AFAICT you only really need an independent result property when you need to show validation errors/previously-submitted data, can't use client-side validation to prevent the bad submission in the first place, and need per-instance UI
In other words you already know when it's valuable - so we shouldn't remove it. One example are validation errors that happen on the server, like "you are not allowed to delete this". Another is to disable the button while a submission is in progress (which we need to add anyway AFAICT).
Related: #7175
I'm tempted to suggest just throwing formaction onto the form object itself
Sounds tempting indeed. I fear that the onclick handler intercepting unexpectedly could throw people off, also it would probably confuse people why there are more attributes than necessary on the form.
When coming up with an alternative name I would then choose something that is not an attribute name, that somehow brings across the intent. secondaryAction
or something like that.
Yeah, not suggesting removing for
, just the docs for for
until we can come up with a good example.
Consensus on naming appears to be formAction
-> buttonProps
, will make that change
Re example: what about pending UI which is made possible through a new Boolean (which we should have anyway) form.submitting
?
Ooh that's a good idea. In the interests of shipping I think it should probably be a follow-up PR but yeah I like that
updates
and withOverride
for command * implement updates
and withOverride
for form * cleanup * Prevent state_unsafe_mutation error * restrict to 0 or 1 argument, enforce validation * validation tests * tweak * comment out for the time being * remove validate function * lint * guard * bump Svelte version * silence type errors * Update packages/kit/src/runtime/app/server/remote.js Co-authored-by: Paolo Ricciuti ricciutipaolo@gmail.com * fix * update playground --------- Co-authored-by: Dominic Gannaway trueadm@users.noreply.github.com Co-authored-by: Rich Harris rich.harris@vercel.com Co-authored-by: Paolo Ricciuti ricciutipaolo@gmail.comCo-authored-by: Rich Harris richard.a.harris@gmail.com