Skip to content

Commit f9c1d46

Browse files
committed
fix instance caching for multiple factory invocations with the same key
1 parent 32f923e commit f9c1d46

File tree

3 files changed

+39
-68
lines changed

3 files changed

+39
-68
lines changed

documentation/docs/20-core-concepts/60-remote-functions.md

Lines changed: 38 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -288,12 +288,11 @@ export const createPost = form(
288288
<!--- file: src/routes/blog/new/+page.svelte --->
289289
<script>
290290
import { createPost } from '../data.remote';
291-
const form = createPost();
292291
</script>
293292

294293
<h1>Create a new post</h1>
295294

296-
<form {...form}>
295+
<form {...createPost()}>
297296
<!-- form content goes here -->
298297

299298
<button>Publish!</button>
@@ -309,20 +308,15 @@ As with `query`, if the callback uses the submitted `data`, it should be [valida
309308
A form is composed of a set of _fields_, which are defined by the schema. In the case of `createPost`, we have two fields, `title` and `content`, which are both strings. To get the attributes for a field, call its `.as(...)` method, specifying which [input type](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input#input_types) to use:
310309
311310
```svelte
312-
<script>
313-
import { createPost } from '../data.remote';
314-
const form = createPost();
315-
</script>
316-
317-
<form {...form}>
311+
<form {...createPost()}>
318312
<label>
319313
<h2>Title</h2>
320-
+++<input {...form.fields.title.as('text')} />+++
314+
+++<input {...createPost().fields.title.as('text')} />+++
321315
</label>
322316

323317
<label>
324318
<h2>Write your post</h2>
325-
+++<textarea {...form.fields.content.as('text')}></textarea>+++
319+
+++<textarea {...createPost().fields.content.as('text')}></textarea>+++
326320
</label>
327321

328322
<button>Publish!</button>
@@ -357,11 +351,10 @@ export const createProfile = form(datingProfile, (data) => { /* ... */ });
357351
<script>
358352
import { createProfile } from './data.remote';
359353

360-
const form = createProfile();
361-
const { name, photo, info, attributes } = form.fields;
354+
const { name, photo, info, attributes } = createProfile().fields;
362355
</script>
363356

364-
<form {...form} enctype="multipart/form-data">
357+
<form {...createProfile()} enctype="multipart/form-data">
365358
<label>
366359
<input {...name.as('text')} /> Name
367360
</label>
@@ -408,17 +401,12 @@ export const survey = form(
408401
```
409402
410403
```svelte
411-
<script>
412-
import { survey } from '../data.remote';
413-
const form = survey();
414-
</script>
415-
416-
<form {...form}>
404+
<form {...survey()}>
417405
<h2>Which operating system do you use?</h2>
418406

419407
{#each ['windows', 'mac', 'linux'] as os}
420408
<label>
421-
<input {...form.fields.operatingSystem.as('radio', os)}>
409+
<input {...survey().fields.operatingSystem.as('radio', os)}>
422410
{os}
423411
</label>
424412
{/each}
@@ -427,7 +415,7 @@ export const survey = form(
427415

428416
{#each ['html', 'css', 'js'] as language}
429417
<label>
430-
<input {...form.fields.languages.as('checkbox', language)}>
418+
<input {...survey().fields.languages.as('checkbox', language)}>
431419
{language}
432420
</label>
433421
{/each}
@@ -439,18 +427,18 @@ export const survey = form(
439427
Alternatively, you could use `select` and `select multiple`:
440428
441429
```svelte
442-
<form {...form}>
430+
<form {...survey()}>
443431
<h2>Which operating system do you use?</h2>
444432

445-
<select {...form.fields.operatingSystem.as('select')}>
433+
<select {...survey().fields.operatingSystem.as('select')}>
446434
<option>windows</option>
447435
<option>mac</option>
448436
<option>linux</option>
449437
</select>
450438

451439
<h2>Which languages do you write code in?</h2>
452440

453-
<select {...form.fields.languages.as('select multiple')}>
441+
<select {...survey().fields.languages.as('select multiple')}>
454442
<option>html</option>
455443
<option>css</option>
456444
<option>js</option>
@@ -504,30 +492,25 @@ The `invalid` function works as both a function and a proxy:
504492
If the submitted data doesn't pass the schema, the callback will not run. Instead, each invalid field's `issues()` method will return an array of `{ message: string }` objects, and the `aria-invalid` attribute (returned from `as(...)`) will be set to `true`:
505493
506494
```svelte
507-
<script>
508-
import { createPost } from '../data.remote';
509-
const form = createPost();
510-
</script>
511-
512-
<form {...form}>
495+
<form {...createPost()}>
513496
<label>
514497
<h2>Title</h2>
515498

516-
+++ {#each form.fields.title.issues() as issue}
499+
+++ {#each createPost().fields.title.issues() as issue}
517500
<p class="issue">{issue.message}</p>
518501
{/each}+++
519502

520-
<input {...form.fields.title.as('text')} />
503+
<input {...createPost().fields.title.as('text')} />
521504
</label>
522505

523506
<label>
524507
<h2>Write your post</h2>
525508

526-
+++ {#each form.fields.content.issues() as issue}
509+
+++ {#each createPost().fields.content.issues() as issue}
527510
<p class="issue">{issue.message}</p>
528511
{/each}+++
529512

530-
<textarea {...form.fields.content.as('text')}></textarea>
513+
<textarea {...createPost().fields.content.as('text')}></textarea>
531514
</label>
532515

533516
<button>Publish!</button>
@@ -537,7 +520,7 @@ If the submitted data doesn't pass the schema, the callback will not run. Instea
537520
You don't need to wait until the form is submitted to validate the data — you can call `validate()` programmatically, for example in an `oninput` callback (which will validate the data on every keystroke) or an `onchange` callback:
538521
539522
```svelte
540-
<form {...form} oninput={() => form.validate()}>
523+
<form {...createPost()} oninput={() => form.validate()}>
541524
<!-- -->
542525
</form>
543526
```
@@ -551,8 +534,6 @@ For client-side validation, you can specify a _preflight_ schema which will popu
551534
import * as v from 'valibot';
552535
import { createPost } from '../data.remote';
553536

554-
const form = createPost();
555-
556537
const schema = v.object({
557538
title: v.pipe(v.string(), v.nonEmpty()),
558539
content: v.pipe(v.string(), v.nonEmpty())
@@ -561,7 +542,7 @@ For client-side validation, you can specify a _preflight_ schema which will popu
561542

562543
<h1>Create a new post</h1>
563544

564-
<form {...+++form.preflight(schema)+++}>
545+
<form {...+++createPost().preflight(schema)+++}>
565546
<!-- -->
566547
</form>
567548
```
@@ -571,7 +552,7 @@ For client-side validation, you can specify a _preflight_ schema which will popu
571552
To get a list of _all_ issues, rather than just those belonging to a single field, you can use the `fields.allIssues()` method:
572553
573554
```svelte
574-
{#each form.fields.allIssues() as issue}
555+
{#each createPost().fields.allIssues() as issue}
575556
<p>{issue.message}</p>
576557
{/each}
577558
```
@@ -581,35 +562,33 @@ To get a list of _all_ issues, rather than just those belonging to a single fiel
581562
Each field has a `value()` method that reflects its current value. As the user interacts with the form, it is automatically updated:
582563
583564
```svelte
584-
<form {...form}>
565+
<form {...createPost()}>
585566
<!-- -->
586567
</form>
587568

588569
<div class="preview">
589-
<h2>{form.fields.title.value()}</h2>
590-
<div>{@html render(form.fields.content.value())}</div>
570+
<h2>{createPost().fields.title.value()}</h2>
571+
<div>{@html render(createPost().fields.content.value())}</div>
591572
</div>
592573
```
593574
594-
Alternatively, `form.fields.value()` would return a `{ title, content }` object.
575+
Alternatively, `createPost().fields.value()` would return a `{ title, content }` object.
595576
596577
You can update a field (or a collection of fields) via the `set(...)` method:
597578
598579
```svelte
599580
<script>
600581
import { createPost } from '../data.remote';
601582

602-
const form = createPost();
603-
604583
// this...
605-
form.fields.set({
584+
createPost().fields.set({
606585
title: 'My new blog post',
607586
content: 'Lorem ipsum dolor sit amet...'
608587
});
609588

610589
// ...is equivalent to this:
611-
form.fields.title.set('My new blog post');
612-
form.fields.content.set('Lorem ipsum dolor sit amet');
590+
createPost().fields.title.set('My new blog post');
591+
createPost().fields.content.set('Lorem ipsum dolor sit amet');
613592
</script>
614593
```
615594
@@ -620,15 +599,15 @@ In the case of a non-progressively-enhanced form submission (i.e. where JavaScri
620599
You can prevent sensitive data (such as passwords and credit card numbers) from being sent back to the user by using a name with a leading underscore:
621600
622601
```svelte
623-
<form {...form}>
602+
<form {...register()}>
624603
<label>
625604
Username
626-
<input {...form.fields.username.as('text')} />
605+
<input {...register().fields.username.as('text')} />
627606
</label>
628607

629608
<label>
630609
Password
631-
<input +++{...form.fields._password.as('password')}+++ />
610+
<input +++{...register().fields._password.as('password')}+++ />
632611
</label>
633612

634613
<button>Sign up!</button>
@@ -687,7 +666,7 @@ The second is to drive the single-flight mutation from the client, which we'll s
687666
688667
### Returns and redirects
689668
690-
The example above uses [`redirect(...)`](@sveltejs-kit#redirect), which sends the user to the newly created page. Alternatively, the callback could return data, in which case it would be available as `form.result`:
669+
The example above uses [`redirect(...)`](@sveltejs-kit#redirect), which sends the user to the newly created page. Alternatively, the callback could return data, in which case it would be available as `createPost().result`:
691670
692671
```ts
693672
/// file: src/routes/blog/data.remote.js
@@ -732,16 +711,15 @@ export const createPost = form(
732711
<!--- file: src/routes/blog/new/+page.svelte --->
733712
<script>
734713
import { createPost } from '../data.remote';
735-
const form = createPost();
736714
</script>
737715

738716
<h1>Create a new post</h1>
739717

740-
<form {...form}>
718+
<form {...createPost()}>
741719
<!-- -->
742720
</form>
743721

744-
{#if form.result?.success}
722+
{#if createPost().result?.success}
745723
<p>Successfully published!</p>
746724
{/if}
747725
```
@@ -761,12 +739,11 @@ We can customize what happens when the form is submitted with the `enhance` meth
761739
<script>
762740
import { createPost } from '../data.remote';
763741
import { showToast } from '$lib/toast';
764-
const form = createPost();
765742
</script>
766743

767744
<h1>Create a new post</h1>
768745

769-
<form {...form.enhance(async ({ form, data, submit }) => {
746+
<form {...createPost().enhance(async ({ form, data, submit }) => {
770747
try {
771748
await submit();
772749
form.reset();
@@ -850,23 +827,21 @@ This attribute exists on the `buttonProps` property of a form object:
850827
<!--- file: src/routes/login/+page.svelte --->
851828
<script>
852829
import { login, register } from '$lib/auth';
853-
const loginForm = login();
854-
const registerForm = register();
855830
</script>
856831

857-
<form {...loginForm}>
832+
<form {...login()}>
858833
<label>
859834
Your username
860-
<input {...loginForm.fields.username.as('text')} />
835+
<input {...login().fields.username.as('text')} />
861836
</label>
862837

863838
<label>
864839
Your password
865-
<input {...loginForm.fields._password.as('password')} />
840+
<input {...login().fields._password.as('password')} />
866841
</label>
867842

868843
<button>login</button>
869-
<button {...registerForm.buttonProps}>register</button>
844+
<button {...register().buttonProps}>register</button>
870845
</form>
871846
```
872847

packages/kit/src/runtime/app/server/remote/form.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ export function form(validate_or_fn, maybe_fn) {
183183

184184
// Check cache for keyed instances
185185
const cache_key = instance_info.id + '|' + JSON.stringify(key);
186+
console.log('cache_key', cache_key);
186187
const cached = (state.form_instances ??= new Map()).get(cache_key);
187188
if (cached) {
188189
return cached;

packages/kit/src/runtime/client/remote-functions/form.svelte.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -589,11 +589,6 @@ export function form(id) {
589589

590590
/** @type {RemoteFormFactory<T, U>} */
591591
const factory = (key) => {
592-
if (key === undefined) {
593-
// For the default instance (no key), create a new instance each time
594-
return create_instance();
595-
}
596-
597592
const entry = instances.get(key) ?? { count: 0, instance: create_instance(key) };
598593

599594
try {

0 commit comments

Comments
 (0)